Пример #1
0
        public void Reset(int bodyCapacity, int contactCapacity, int jointCapacity, IContactListener listener)
        {
            _bodyCapacity = bodyCapacity;
	        _contactCapacity = contactCapacity;
	        _jointCapacity	 = jointCapacity;
	        _bodyCount = 0;
	        _jointCount = 0;

	        _listener = listener;

            if (_bodies == null || _bodies.Length < bodyCapacity)
            {
                _bodies = new Body[bodyCapacity];
            }

            if (_contacts == null || _contacts.Length < contactCapacity)
            {
                _contacts = new Contact[contactCapacity * 2];
            }

            if (_joints == null || _joints.Length < jointCapacity)
            {
                _joints = new Joint[jointCapacity * 2];
            }
        }
        public Player(GameContent gameContent, World world, Vector2 position)
        {
            this.gameContent = gameContent;
            this.world = world;

            idle = new Animation(gameContent.playerIdle, 2, 2f, true, new Vector2(0.5f));
            walk = new Animation(gameContent.playerWalk, 2, 0.2f, true, new Vector2(0.5f));
            die = new Animation(gameContent.playerDie, 2, 0.2f, false, new Vector2(0.5f));

            animationPlayer.PlayAnimation(idle);

            BodyDef bd = new BodyDef();
            bd.position = position / gameContent.b2Scale;
            bd.type = BodyType.Dynamic;
            bd.linearDamping = 10;
            body = world.CreateBody(bd);

            CircleShape cs = new CircleShape();
            cs._radius = (float)(idle.FrameWidth - 1) / gameContent.b2Scale / 2;
            FixtureDef fd = new FixtureDef();
            fd.shape = cs;
            fd.filter.groupIndex = -1;

            body.CreateFixture(fd);
        }
        public Enemy(World world, GameContent gameContent, int index, Vector2 position)
        {
            this.gameContent = gameContent;

            walk = new Animation(gameContent.enemy[index], 2, 0.15f, true, new Vector2(0.5f));
            animationPlayer.PlayAnimation(walk);

            if (index == 0) linearImpulse = 1f / 2;
            else linearImpulse = 0.75f / 2;

            BodyDef bd = new BodyDef();
            bd.position = position / gameContent.b2Scale;
            bd.type = BodyType.Dynamic;
            bd.linearDamping = 10;
            body = world.CreateBody(bd);

            CircleShape cs = new CircleShape();
            cs._radius = (float)(walk.FrameWidth - 1) / gameContent.b2Scale / 2;
            FixtureDef fd = new FixtureDef();
            fd.shape = cs;
            fd.filter.groupIndex = -1;

            body.CreateFixture(fd);
            body.SetUserData(this);
        }
Пример #4
0
        public void addPhysicsObj(GameObject _gameObj,Body _body)
        {
            PhysicsObj obj = new PhysicsObj(_gameObj, _body);
            _gameObj.physicsObj = obj;

            this.privActiveAddToFront((ManLink)obj, ref this.active);
        }
        public Soldier(Shape shape, Vector2 position, GameContent gameContent, World world)
        {
            this.gameContent = gameContent;
            this.world = world;

            idle = new Animation(gameContent.idle[(int)shape], 20f, false);
            walk = new Animation(gameContent.walk[(int)shape], 0.15f, true);
            animationPlayer.PlayAnimation(idle);

            MaxHealth = 10; health = gameContent.random.Next(2, 10);
            MaxReloadTime = gameContent.random.Next(50); reloadTime = 0;

            CircleShape cShape = new CircleShape();
            cShape._radius = (Size + 2) / 2 / gameContent.b2Scale;

            BodyDef bd = new BodyDef();
            bd.fixedRotation = true;
            bd.type = BodyType.Dynamic;
            bd.position = position / gameContent.b2Scale;
            body = world.CreateBody(bd);
            //body.SetLinearDamping(10);

            FixtureDef fd = new FixtureDef();
            fd.shape = cShape;
            fd.restitution = 0.5f;
            fd.friction = .1f;
            fd.density = .1f;

            body.CreateFixture(fd);
            body.SetUserData(this);
        }
Пример #6
0
        public Car(Vector2 position, GameContent gameContent, World world)
        {
            this.world = world;
            this.gameContent = gameContent;

            BodyDef bd = new BodyDef();
            bd.position = position / gameContent.Scale;
            bd.type = BodyType.Dynamic;
            bd.bullet = true;

            body = world.CreateBody(bd);
            body.SetLinearDamping(1f); body.SetAngularDamping(0.1f);

            float width = gameContent.playerCar.Width, height = gameContent.playerCar.Height;

            FixtureDef fd = new FixtureDef();
            fd.density = 0.1f;
            //fd.restitution = .1f;

            CircleShape cs = new CircleShape();
            cs._p = new Vector2(0, -(height - width / 2)) / gameContent.Scale;
            cs._radius = width / 2 / gameContent.Scale;
            fd.shape = cs; body.CreateFixture(fd);

            PolygonShape ps = new PolygonShape();
            ps.SetAsBox(width / 2 / gameContent.Scale, (height - width / 2) / 2 / gameContent.Scale,
                new Vector2(0, -(height - width / 2) / 2) / gameContent.Scale, 0);
            fd.shape = ps; body.CreateFixture(fd);

            CreateWheels();
        }
Пример #7
0
        public override bool init()
        {
            if (!base.init())
                return false;
            if (!base.init())
            {
                return false;
            }

            CCSize winSize = CCDirector.sharedDirector().getWinSize();
            title = CCLabelTTF.labelWithString("FootBall", "Arial", 24);
            title.position = new CCPoint(winSize.width / 2, winSize.height - 50);
            this.addChild(title, 1);
            ball = CCSprite.spriteWithFile(@"images/ball");
            ball.position = new CCPoint(100, 300);
            this.addChild(ball);
            Vector2 gravity = new Vector2(0.0f, -30.0f);
            bool doSleep = true;
            world = new World(gravity, doSleep);
            /////////////////////////
            BodyDef groundBodyDef = new BodyDef();
            groundBodyDef.position = new Vector2(0, 0);
            Body groundBody = world.CreateBody(groundBodyDef);
            PolygonShape groundBox = new PolygonShape();
            FixtureDef boxShapeDef = new FixtureDef();
            boxShapeDef.shape = groundBox;

            groundBox.SetAsEdge(new Vector2(0, 0), new Vector2((float)(winSize.width / PTM_RATIO), 0));
            groundBody.CreateFixture(boxShapeDef);
            groundBox.SetAsEdge(new Vector2(0, 0), new Vector2(0, (float)(winSize.height / PTM_RATIO)));
            groundBody.CreateFixture(boxShapeDef);
            groundBox.SetAsEdge(new Vector2(0, (float)(winSize.height / PTM_RATIO)),
                new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)));
            groundBody.CreateFixture(boxShapeDef);
            groundBox.SetAsEdge(new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)),
                new Vector2((float)(winSize.width / PTM_RATIO), 0));
            groundBody.CreateFixture(boxShapeDef);

            BodyDef ballBodyDef = new BodyDef();
            ballBodyDef.type = BodyType.Dynamic;
            ballBodyDef.position = new Vector2(
                (float)(100 / PTM_RATIO),
                (float)(300 / PTM_RATIO));
            ballBodyDef.userData = ball;
            body = world.CreateBody(ballBodyDef);

            CircleShape circle = new CircleShape();
            circle._radius = (float)(26.0 / PTM_RATIO);

            FixtureDef ballShapeDef = new FixtureDef();
            ballShapeDef.shape = circle;
            ballShapeDef.density = 1.0f;
            ballShapeDef.friction = 0.0f;
            ballShapeDef.restitution = 1.0f;
            body.CreateFixture(ballShapeDef);

            this.schedule(tick);
            return true;
        }
Пример #8
0
 public Terrain(World world)
 {
     mWorld = world;
     mBodyDef = new BodyDef();
     mBody = world.CreateBody(mBodyDef);
     Generate();
     GenerateDrawVertexs();
 }
Пример #9
0
        // Point-to-point constraint
        // C = p2 - p1
        // Cdot = v2 - v1
        //      = v2 + cross(w2, r2) - v1 - cross(w1, r1)
        // J = [-I -r1_skew I r2_skew ]
        // Identity used:
        // w k % (rx i + ry j) = w * (-ry i + rx j)

        // Angle constraint
        // C = angle2 - angle1 - referenceAngle
        // Cdot = w2 - w1
        // J = [0 0 -1 0 0 1]
        // K = invI1 + invI2

	    public void Initialize(Body b1, Body b2, Vector2 anchor)
        {
	        bodyA = b1;
	        bodyB = b2;
	        localAnchorA = bodyA.GetLocalPoint(anchor);
	        localAnchorB = bodyB.GetLocalPoint(anchor);
            referenceAngle = bodyB.GetAngle() - bodyA.GetAngle();
        }
Пример #10
0
	    /// Initialize the bodies, anchors, axis, and reference angle using the world
	    /// anchor and world axis.
        public void Initialize(Body b1, Body b2, Vector2 anchor, Vector2 axis)
        {
	        bodyA = b1;
	        bodyB = b2;
	        localAnchorA = bodyA.GetLocalPoint(anchor);
	        localAnchorB = bodyB.GetLocalPoint(anchor);
	        localAxisA = bodyA.GetLocalVector(axis);
        }
Пример #11
0
        // Point-to-point constraint
        // Cdot = v2 - v1
        //      = v2 + cross(w2, r2) - v1 - cross(w1, r1)
        // J = [-I -r1_skew I r2_skew ]
        // Identity used:
        // w k % (rx i + ry j) = w * (-ry i + rx j)

        // Angle constraint
        // Cdot = w2 - w1
        // J = [0 0 -1 0 0 1]
        // K = invI1 + invI2
	    public void Initialize(Body b1, Body b2,
					    Vector2 anchor1, Vector2 anchor2)
        {
	        bodyA = b1;
	        bodyB = b2;
	        localAnchorA = bodyA.GetLocalPoint(anchor1);
	        localAnchorB = bodyB.GetLocalPoint(anchor2);
        }
Пример #12
0
	    /// Initialize the bodies, anchors, and length using the world
	    /// anchors.
        // 1-D rained system
        // m (v2 - v1) = lambda
        // v2 + (beta/h) * x1 + gamma * lambda = 0, gamma has units of inverse mass.
        // x2 = x1 + h * v2

        // 1-D mass-damper-spring system
        // m (v2 - v1) + h * d * v2 + h * k * 

        // C = norm(p2 - p1) - L
        // u = (p2 - p1) / norm(p2 - p1)
        // Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1))
        // J = [-u -cross(r1, u) u cross(r2, u)]
        // K = J * invM * JT
        //   = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2
	    public void Initialize(Body b1, Body b2,
					    Vector2 anchor1, Vector2 anchor2, float maxlength)
        {
	        bodyA = b1;
	        bodyB = b2;
	        localAnchorA = bodyA.GetLocalPoint(anchor1);
	        localAnchorB = bodyB.GetLocalPoint(anchor2);
            length = maxlength;
        }
Пример #13
0
        public DrawUnit(Sprite sprite, Body body, World world)
            : base(body, world)
        {
            _sprite = sprite;
            _eventManager = world.EventManager;

            _listener = new EventListener(Constants.TIME_TICKS_EVENT);
            _listener.Handler = e => Update();
            _eventManager.Register(_listener);
        }
        public Apple(Vector2 position, Body ground, GameContent gameContent, World world)
            : this(null, gameContent, world)
        {
            this.ground = ground;
            body.Position = position;
            originalPostion = position;
            State = LeafState.Drop;

            fallenFromAir = true;
        }
Пример #15
0
	    /// Initialize the bodies, anchors, and length using the world
	    /// anchors.
        // 1-D rained system
        // m (v2 - v1) = lambda
        // v2 + (beta/h) * x1 + gamma * lambda = 0, gamma has units of inverse mass.
        // x2 = x1 + h * v2

        // 1-D mass-damper-spring system
        // m (v2 - v1) + h * d * v2 + h * k * 

        // C = norm(p2 - p1) - L
        // u = (p2 - p1) / norm(p2 - p1)
        // Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1))
        // J = [-u -cross(r1, u) u cross(r2, u)]
        // K = J * invM * JT
        //   = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2
	    public void Initialize(Body b1, Body b2,
					    Vector2 anchor1, Vector2 anchor2)
        {
	        bodyA = b1;
	        bodyB = b2;
	        localAnchorA = bodyA.GetLocalPoint(anchor1);
	        localAnchorB = bodyB.GetLocalPoint(anchor2);
	        Vector2 d = anchor2 - anchor1;
	        length = d.Length();
        }
Пример #16
0
 public void PostSolve(Contact contact, ref ContactImpulse impulse)
 {
     Body[] bodies = new Body[2];
     bodies[0] = contact.GetFixtureA().GetBody();
     bodies[1] = contact.GetFixtureB().GetBody();
     mBodies.Add(bodies);
     if (mBodies.Count > 10000)
     {
         mBodies.Clear();
         Console.WriteLine("Clear contacts.");
     }
 }
        public Asteroid(GameContent gameContent, int index, Body body)
        {
            this.gameContent = gameContent;
            tex = gameContent.asteroid[index];
            this.body = body;
            body.SetUserData(this);
            originalPosition = body.Position;

            for (int i = 0; i < 5; i++)
                blastTex[i] = gameContent.asteroid[(index + i) % 16];

            blastSound = gameContent.boom[index % 3];
            blastSoundInstance = blastSound.CreateInstance();
            blastSoundInstance.Volume = 0.8f;
        }
Пример #18
0
        public void addBodyToDestroy(Body b)
        {
            BodyNode bodyNode = new BodyNode(b);

            if (destroyHead == null)
            {
                destroyHead = bodyNode;
                bodyNode.next = null;
                bodyNode.prev = null;
            }
            else
            {
                bodyNode.next = destroyHead;
                destroyHead.prev = bodyNode;
                destroyHead = bodyNode;
            }
        }
Пример #19
0
        public Box(World world, Vector2 position, Vector2 size, string texture, bool isStatic, Player player, float health = 100)
        {
            ObjectType = EObjectType.Box;
            mHealth = health;
            mStartHealth = health;
            mIsDestroyed = false;
            mSize = size;
            mWorld = world;
            mTexture = texture;
            mPlayer = player;
            DestroyTime = null;
            PolygonShape polygonShape = new PolygonShape();
            polygonShape.SetAsBox(size.X / 2f, size.Y / 2f);

            BodyDef bodyDef = new BodyDef();
            bodyDef.position = position;
            bodyDef.bullet = true;
            if (isStatic)
            {
                bodyDef.type = BodyType.Static;
            }
            else
            {
                bodyDef.type = BodyType.Dynamic;
            }
            mBody = world.CreateBody(bodyDef);

            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = polygonShape;//Форма
            fixtureDef.density = 0.1f;//Плотность
            fixtureDef.friction = 0.3f;//Сила трения
            fixtureDef.restitution = 0f;//Отскок

            Filter filter = new Filter();
            filter.maskBits = (ushort)(EntityCategory.Player1 | EntityCategory.Player2);
            filter.categoryBits = (ushort)player.PlayerType;

            var fixture = mBody.CreateFixture(fixtureDef);
            fixture.SetFilterData(ref filter);
            MassData data = new MassData();
            data.mass = 0.01f;
            mBody.SetUserData(this);
        }
Пример #20
0
	    /// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors.
        public void Initialize(Body b1, Body b2,
                        Vector2 ga1, Vector2 ga2,
					    Vector2 anchor1, Vector2 anchor2,
					    float r)
        {
	        bodyA = b1;
	        bodyB = b2;
	        groundAnchorA = ga1;
	        groundAnchorB = ga2;
	        localAnchorA = bodyA.GetLocalPoint(anchor1);
	        localAnchorB = bodyB.GetLocalPoint(anchor2);
	        Vector2 d1 = anchor1 - ga1;
	        lengthA = d1.Length();
	        Vector2 d2 = anchor2 - ga2;
	        lengthB = d2.Length();
	        ratio = r;
	        Debug.Assert(ratio > Settings.b2_epsilon);
	        float C = lengthA + ratio * lengthB;
	        maxLengthA = C - ratio * b2_minPulleyLength;
	        maxLengthB = (C - b2_minPulleyLength) / ratio;
        }
        public Branch(Path2D path, GameContent gameContent, World world, Branch nearestBranch)
        {
            this.gameContent = gameContent;
            dot = gameContent.dot;
            circle = gameContent.jointCircle;
            square = gameContent.jointSquare;
            cursor = gameContent.cursor;

            BodyDef bd = new BodyDef();
            bd.position = path.Keys[0];
            bd.type = BodyType.Dynamic;
            body = world.CreateBody(bd);

            fixtureCount = path.Keys.Count;
            for (int i = 0; i < path.Keys.Count; i++)
                CreateFixture(path.Keys[i] - path.Keys[0]);

            if (nearestBranch != null)
            {
                RevoluteJointDef revJd = new RevoluteJointDef();
                revJd.bodyA = body;
                revJd.bodyB = nearestBranch.body;

                revJd.localAnchorA = Vector2.Zero;

                AABB aabb; nearestBranch.nearestFixture.GetAABB(out aabb);
                Vector2 p = aabb.GetCenter();
                revJd.localAnchorB = nearestBranch.nearestFixture.GetBody().GetLocalPoint(p);

                revJd.enableMotor = true;
                revJd.referenceAngle = nearestBranch.nearestFixture.GetBody().Rotation;

                revoJoint = (RevoluteJoint)world.CreateJoint(revJd);
                revoJoint.SetUserData((Branch)nearestBranch);

                nearestBranch.nearestFixture.SetUserData((Branch)this);
            }

            newGrow = true;
        }
        public Equipment(EquipmentName equipName, GameContent gameContent, World world)
        {
            this.gameContent = gameContent;
            this.world = world;

            this.equipName = equipName;
            BodyDef bd = new BodyDef();
            bd.type = BodyType.Dynamic;
            body = world.CreateBody(bd);

            equipmentData = gameContent.content.Load<EquipmentData>("Graphics/" + equipName.ToString());

            topLeftVertex = equipmentData.TopLeftVertex;
            origin = equipmentData.Origin;
            rotationButtonPos = equipmentData.RotationButtonPosition;

            rightClampPositionX = equipmentData.ClampData.RightClampPositionX;
            clampRotation = equipmentData.ClampData.RotationInDeg / 180f * (float)Math.PI;
            clampEnabled = equipmentData.ClampData.ClampEnabled;

            SetFixtures();

            // Collide only with Ground but not with itself and bonded Filter
            mouseFilter = new Filter();
            mouseFilter.categoryBits = 0x0002; mouseFilter.maskBits = 0x0001; mouseFilter.groupIndex = -2;

            // Collide with every thing
            groundFilter = new Filter();
            groundFilter.categoryBits = 0x0001; groundFilter.maskBits = 65535; groundFilter.groupIndex = 0;

            equipFilter = new Filter();
            equipFilter.categoryBits = 0x0002; equipFilter.maskBits = 0x0001; equipFilter.groupIndex = 2;

            //SetMode(false, false);

            body.SetUserData((EquipmentName)equipName);
        }
        public Level(ScreenManager screenManager, int levelIndex)
        {
            this.gameContent = screenManager.GameContent;
            this.levelIndex = levelIndex;

            camera = new Camera2D();

            groundBody = world.CreateBody(new BodyDef());
            LoadTiles(levelIndex);

            UpdateCameraChaseTarget(new GameTime());

            Vector2[] v = {Vector2.Zero, new Vector2(tiles.GetLength(0), 0),
                              new Vector2(tiles.GetLength(0), tiles.GetLength(1)),
                              new Vector2(0, tiles.GetLength(1)), Vector2.Zero};

            for (int i = 0; i < v.Length - 1; i++)
            {
                PolygonShape ps = new PolygonShape();
                ps.SetAsEdge(v[i] * Tile.Width / gameContent.b2Scale, v[i + 1] * Tile.Width / gameContent.b2Scale);

                groundBody.CreateFixture(ps, 0);
            }
        }
        public Level(GameContent gameContent)
        {
            world = new World(atomGravity, false);
            this.gameContent = gameContent;

            if (gameContent.levelIndex == -1) this.isLAB = true;

            camera = new Camera2D();

            if (!isLAB) LoadLevelComponent();
            else
            {
                labComponent = new LabComponent(gameContent, world);
                editMode = true;
                world.Gravity = equipGravity;
                camera.Scale = targetScale = scale = labComponent.EqScale;
                camera.Position = new Vector2(labComponent.Width, labComponent.Height) / 2 * Camera2D.PhoneScale;
                camera.Speed = 500;
                camera.ScrollBar = new Vector2(50, 50);
                camera.ScrollArea = new Vector2(labComponent.Width, labComponent.Height) * Camera2D.PhoneScale;
            }

            mouseGroundBody = world.CreateBody(new BodyDef());
        }
Пример #25
0
        /// <summary> Destroy a joint. This may cause the connected bodies to begin colliding.
        /// </summary> <warning> This function is locked during callbacks.
        /// </warning>
        public void DestroyJoint(Joint j)
        {
            Debug.Assert(!IsLocked);
            if (IsLocked)
            {
                return;
            }

            bool collideConnected = j._collideConnected;

            // Remove from the doubly linked list.
            if (j._prev != null)
            {
                j._prev._next = j._next;
            }

            if (j._next != null)
            {
                j._next._prev = j._prev;
            }

            if (j == _jointList)
            {
                _jointList = j._next;
            }

            // Disconnect from island graph.
            Body bodyA = j._bodyA;
            Body bodyB = j._bodyB;

            // Wake up connected bodies.
            bodyA.SetAwake(true);
            bodyB.SetAwake(true);

            // Remove from body 1.
            if (j._edgeA.Prev != null)
            {
                j._edgeA.Prev.Next = j._edgeA.Next;
            }

            if (j._edgeA.Next != null)
            {
                j._edgeA.Next.Prev = j._edgeA.Prev;
            }

            if (j._edgeA == bodyA._jointList)
            {
                bodyA._jointList = j._edgeA.Next;
            }

            j._edgeA.Prev = null;
            j._edgeA.Next = null;

            // Remove from body 2
            if (j._edgeB.Prev != null)
            {
                j._edgeB.Prev.Next = j._edgeB.Next;
            }

            if (j._edgeB.Next != null)
            {
                j._edgeB.Next.Prev = j._edgeB.Prev;
            }

            if (j._edgeB == bodyB._jointList)
            {
                bodyB._jointList = j._edgeB.Next;
            }

            j._edgeB.Prev = null;
            j._edgeB.Next = null;

            Debug.Assert(_jointCount > 0);
            --_jointCount;

            // If the joint prevents collisions, then flag any contacts for filtering.
            if (collideConnected == false)
            {
                ContactEdge edge = bodyB.GetContactList();
                while (edge != null)
                {
                    if (edge.Other == bodyA)
                    {
                        // Flag the contact for filtering at the next time step (where either
                        // body is awake).
                        edge.Contact.FlagForFiltering();
                    }

                    edge = edge.Next;
                }
            }
        }
Пример #26
0
        /// <summary>
        /// Call this to initialize a Behaviour with data supplied in a file.
        /// </summary>
        /// <param name="fileName">The file to load from.</param>
        public override void LoadContent(String fileName)
        {
            base.LoadContent(fileName);

            // Load the definiton for this object.
            SimulatedPhysicsDefinition def = GameObjectManager.pInstance.pContentManager.Load<SimulatedPhysicsDefinition>(fileName);

            // Create the body representing this object in the physical world.
            BodyDef bd = new BodyDef();
            bd.type = BodyType.Dynamic;
            bd.position = PhysicsManager.pInstance.ScreenToPhysicalWorld(new Vector2(640.0f, 340.0f));
            bd.fixedRotation = true;
            bd.linearDamping = 1.0f;
            mBody = PhysicsManager.pInstance.pWorld.CreateBody(bd);

            /*
            // A bunch of code to create a capsule.  Not using it because it has all the same problems as
            // a box when it comes to catching edges and such.
            var shape = new PolygonShape();
            Vector2[] v = new Vector2[8];

            Double increment = System.Math.PI * 2.0 / (v.Length - 2);
            Double theta = 0.0;

            Vector2 center = PhysicsManager.pInstance.ScreenToPhysicalWorld(new Vector2(0.0f, 8.0f));
            Single radius = PhysicsManager.pInstance.ScreenToPhysicalWorld(8.0f);
            for (Int32 i = 0; i < v.Length; i++)
            {
                v[i] = center + radius * new Vector2((float)System.Math.Cos(theta), (float)System.Math.Sin(theta));

                if (i == (v.Length / 2) - 1)
                {
                    center = PhysicsManager.pInstance.ScreenToPhysicalWorld(new Vector2(0.0f, -8.0f));
                    i++;
                    v[i] = center + radius * new Vector2((float)System.Math.Cos(theta), (float)System.Math.Sin(theta));
                }
                theta += increment;
            }

            //v = v.Reverse().ToArray();

            shape.Set(v, v.Length);

            var fd = new FixtureDef();
            fd.shape = shape;
            fd.restitution = 0.0f;
            fd.friction = 0.5f;
            fd.density = 1.0f;
            mBody.CreateFixture(fd);
            */

            var shape = new PolygonShape();
            shape.SetAsBox(PhysicsManager.pInstance.ScreenToPhysicalWorld(8.0f), PhysicsManager.pInstance.ScreenToPhysicalWorld(8.0f));

            var fd = new FixtureDef();
            fd.shape = shape;
            fd.restitution = 0.0f;
            fd.friction = 0.5f;
            fd.density = 1.0f;
            //mBody.CreateFixture(fd);

            var circle = new CircleShape();
            circle._radius = PhysicsManager.pInstance.ScreenToPhysicalWorld(8);
            circle._p = PhysicsManager.pInstance.ScreenToPhysicalWorld(new Vector2(0.0f, 8.0f));

            fd = new FixtureDef();
            fd.shape = circle;
            fd.restitution = 0.0f;
            fd.friction = 0.5f;
            fd.density = 1.5f;
            mBody.CreateFixture(fd);

            circle = new CircleShape();
            circle._radius = PhysicsManager.pInstance.ScreenToPhysicalWorld(8);
            circle._p = PhysicsManager.pInstance.ScreenToPhysicalWorld(new Vector2(0.0f, -8.0f));

            fd = new FixtureDef();
            fd.shape = circle;
            fd.restitution = 0.0f;
            fd.friction = 0.5f;
            fd.density = 1.5f;
            mBody.CreateFixture(fd);
        }
Пример #27
0
        // Update the contact manifold and touching status.
        // Note: do not assume the fixture AABBs are overlapping or are valid.
        internal void Update(IContactListener listener)
        {
            Manifold oldManifold = _manifold;

            // Re-enable this contact.
            _flags |= ContactFlags.Enabled;

            bool touching    = false;
            bool wasTouching = (_flags & ContactFlags.Touching) == ContactFlags.Touching;

            bool sensorA = _fixtureA.IsSensor();
            bool sensorB = _fixtureB.IsSensor();
            bool sensor  = sensorA || sensorB;

            Body      bodyA = _fixtureA.GetBody();
            Body      bodyB = _fixtureB.GetBody();
            Transform xfA; bodyA.GetTransform(out xfA);
            Transform xfB; bodyB.GetTransform(out xfB);

            // Is this contact a sensor?
            if (sensor)
            {
                Shape shapeA = _fixtureA.GetShape();
                Shape shapeB = _fixtureB.GetShape();
                touching = AABB.TestOverlap(shapeA, _indexA, shapeB, _indexB, ref xfA, ref xfB);

                // Sensors don't generate manifolds.
                _manifold._pointCount = 0;
            }
            else
            {
                Evaluate(ref _manifold, ref xfA, ref xfB);
                touching = _manifold._pointCount > 0;

                // Match old contact ids to new contact ids and copy the
                // stored impulses to warm start the solver.
                for (int i = 0; i < _manifold._pointCount; ++i)
                {
                    ManifoldPoint mp2 = _manifold._points[i];
                    mp2.NormalImpulse  = 0.0f;
                    mp2.TangentImpulse = 0.0f;
                    ContactID id2   = mp2.Id;
                    bool      found = false;

                    for (int j = 0; j < oldManifold._pointCount; ++j)
                    {
                        ManifoldPoint mp1 = oldManifold._points[j];

                        if (mp1.Id.Key == id2.Key)
                        {
                            mp2.NormalImpulse  = mp1.NormalImpulse;
                            mp2.TangentImpulse = mp1.TangentImpulse;
                            found = true;
                            break;
                        }
                    }
                    if (found == false)
                    {
                        mp2.NormalImpulse  = 0.0f;
                        mp2.TangentImpulse = 0.0f;
                    }

                    _manifold._points[i] = mp2;
                }

                if (touching != wasTouching)
                {
                    bodyA.SetAwake(true);
                    bodyB.SetAwake(true);
                }
            }

            if (touching)
            {
                _flags |= ContactFlags.Touching;
            }
            else
            {
                _flags &= ~ContactFlags.Touching;
            }

            if (wasTouching == false && touching == true && null != listener)
            {
                listener.BeginContact(this);
            }

            if (wasTouching == true && touching == false && null != listener)
            {
                listener.EndContact(this);
            }

            if (sensor == false && null != listener)
            {
                listener.PreSolve(this, ref oldManifold);
            }
        }
Пример #28
0
        internal override void SolveVelocityConstraints(ref TimeStep step)
        {
            Body b1 = _bodyA;
            Body b2 = _bodyB;

            Transform xf1, xf2;

            b1.GetTransform(out xf1);
            b2.GetTransform(out xf2);

            Vector2 r1 = MathUtils.Multiply(ref xf1.R, _localAnchor1 - b1.GetLocalCenter());
            Vector2 r2 = MathUtils.Multiply(ref xf2.R, _localAnchor2 - b2.GetLocalCenter());

            if (_state == LimitState.AtUpper)
            {
                Vector2 v1 = b1._linearVelocity + MathUtils.Cross(b1._angularVelocity, r1);
                Vector2 v2 = b2._linearVelocity + MathUtils.Cross(b2._angularVelocity, r2);

                float Cdot       = -Vector2.Dot(_u1, v1) - _ratio * Vector2.Dot(_u2, v2);
                float impulse    = _pulleyMass * (-Cdot);
                float oldImpulse = _impulse;
                _impulse = Math.Max(0.0f, _impulse + impulse);
                impulse  = _impulse - oldImpulse;

                Vector2 P1 = -impulse * _u1;
                Vector2 P2 = -_ratio * impulse * _u2;
                b1._linearVelocity  += b1._invMass * P1;
                b1._angularVelocity += b1._invI * MathUtils.Cross(r1, P1);
                b2._linearVelocity  += b2._invMass * P2;
                b2._angularVelocity += b2._invI * MathUtils.Cross(r2, P2);
            }

            if (_limitState1 == LimitState.AtUpper)
            {
                Vector2 v1 = b1._linearVelocity + MathUtils.Cross(b1._angularVelocity, r1);

                float Cdot       = -Vector2.Dot(_u1, v1);
                float impulse    = -_limitMass1 * Cdot;
                float oldImpulse = _limitImpulse1;
                _limitImpulse1 = Math.Max(0.0f, _limitImpulse1 + impulse);
                impulse        = _limitImpulse1 - oldImpulse;

                Vector2 P1 = -impulse * _u1;
                b1._linearVelocity  += b1._invMass * P1;
                b1._angularVelocity += b1._invI * MathUtils.Cross(r1, P1);
            }

            if (_limitState2 == LimitState.AtUpper)
            {
                Vector2 v2 = b2._linearVelocity + MathUtils.Cross(b2._angularVelocity, r2);

                float Cdot       = -Vector2.Dot(_u2, v2);
                float impulse    = -_limitMass2 * Cdot;
                float oldImpulse = _limitImpulse2;
                _limitImpulse2 = Math.Max(0.0f, _limitImpulse2 + impulse);
                impulse        = _limitImpulse2 - oldImpulse;

                Vector2 P2 = -impulse * _u2;
                b2._linearVelocity  += b2._invMass * P2;
                b2._angularVelocity += b2._invI * MathUtils.Cross(r2, P2);
            }
        }
Пример #29
0
        /// <summary> Destroy a rigid body given a definition. No reference to the definition
        /// is retained. This function is locked during callbacks.
        /// </summary> <warning> This automatically deletes all associated shapes and joints.
        /// </warning> <warning> This function is locked during callbacks.
        /// </warning>
        public void DestroyBody(Body b)
        {
            Debug.Assert(_bodyCount > 0);
            Debug.Assert(!IsLocked);
            if (IsLocked)
            {
                return;
            }

            // Delete the attached joints.
            JointEdge je = b._jointList;

            while (je != null)
            {
                JointEdge je0 = je;
                je = je.Next;

                if (DestructionListener != null)
                {
                    DestructionListener.SayGoodbye(je0.Joint);
                }

                DestroyJoint(je0.Joint);
            }
            b._jointList = null;

            // Delete the attached contacts.
            ContactEdge ce = b._contactList;

            while (ce != null)
            {
                ContactEdge ce0 = ce;
                ce = ce.Next;
                _contactManager.Destroy(ce0.Contact);
            }
            b._contactList = null;

            // Delete the attached fixtures. This destroys broad-phase proxies.
            Fixture f = b._fixtureList;

            while (f != null)
            {
                Fixture f0 = f;
                f = f._next;

                if (DestructionListener != null)
                {
                    DestructionListener.SayGoodbye(f0);
                }

                f0.DestroyProxies(_contactManager._broadPhase);
                f0.Destroy();
            }
            b._fixtureList  = null;
            b._fixtureCount = 0;

            // Remove world body list.
            if (b._prev != null)
            {
                b._prev._next = b._next;
            }

            if (b._next != null)
            {
                b._next._prev = b._prev;
            }

            if (b == _bodyList)
            {
                _bodyList = b._next;
            }

            --_bodyCount;
        }
Пример #30
0
        internal override bool SolvePositionConstraints(float baumgarte)
        {
            Body b1 = _bodyA;
            Body b2 = _bodyB;

            Vector2 s1 = _groundAnchor1;
            Vector2 s2 = _groundAnchor2;

            float linearError = 0.0f;

            if (_state == LimitState.AtUpper)
            {
                Transform xf1, xf2;
                b1.GetTransform(out xf1);
                b2.GetTransform(out xf2);

                Vector2 r1 = MathUtils.Multiply(ref xf1.R, _localAnchor1 - b1.GetLocalCenter());
                Vector2 r2 = MathUtils.Multiply(ref xf2.R, _localAnchor2 - b2.GetLocalCenter());

                Vector2 p1 = b1._sweep.c + r1;
                Vector2 p2 = b2._sweep.c + r2;

                // Get the pulley axes.
                _u1 = p1 - s1;
                _u2 = p2 - s2;

                float length1 = _u1.Length();
                float length2 = _u2.Length();

                if (length1 > Settings.b2_linearSlop)
                {
                    _u1 *= 1.0f / length1;
                }
                else
                {
                    _u1 = Vector2.Zero;
                }

                if (length2 > Settings.b2_linearSlop)
                {
                    _u2 *= 1.0f / length2;
                }
                else
                {
                    _u2 = Vector2.Zero;
                }

                float C = _ant - length1 - _ratio * length2;
                linearError = Math.Max(linearError, -C);

                C = MathUtils.Clamp(C + Settings.b2_linearSlop, -Settings.b2_maxLinearCorrection, 0.0f);
                float impulse = -_pulleyMass * C;

                Vector2 P1 = -impulse * _u1;
                Vector2 P2 = -_ratio * impulse * _u2;

                b1._sweep.c += b1._invMass * P1;
                b1._sweep.a += b1._invI * MathUtils.Cross(r1, P1);
                b2._sweep.c += b2._invMass * P2;
                b2._sweep.a += b2._invI * MathUtils.Cross(r2, P2);

                b1.SynchronizeTransform();
                b2.SynchronizeTransform();
            }

            if (_limitState1 == LimitState.AtUpper)
            {
                Transform xf1;
                b1.GetTransform(out xf1);

                Vector2 r1 = MathUtils.Multiply(ref xf1.R, _localAnchor1 - b1.GetLocalCenter());
                Vector2 p1 = b1._sweep.c + r1;

                _u1 = p1 - s1;
                float length1 = _u1.Length();

                if (length1 > Settings.b2_linearSlop)
                {
                    _u1 *= 1.0f / length1;
                }
                else
                {
                    _u1 = Vector2.Zero;
                }

                float C = _maxLength1 - length1;
                linearError = Math.Max(linearError, -C);
                C           = MathUtils.Clamp(C + Settings.b2_linearSlop, -Settings.b2_maxLinearCorrection, 0.0f);
                float impulse = -_limitMass1 * C;

                Vector2 P1 = -impulse * _u1;
                b1._sweep.c += b1._invMass * P1;
                b1._sweep.a += b1._invI * MathUtils.Cross(r1, P1);

                b1.SynchronizeTransform();
            }

            if (_limitState2 == LimitState.AtUpper)
            {
                Transform xf2;
                b2.GetTransform(out xf2);

                Vector2 r2 = MathUtils.Multiply(ref xf2.R, _localAnchor2 - b2.GetLocalCenter());
                Vector2 p2 = b2._sweep.c + r2;

                _u2 = p2 - s2;
                float length2 = _u2.Length();

                if (length2 > Settings.b2_linearSlop)
                {
                    _u2 *= 1.0f / length2;
                }
                else
                {
                    _u2 = Vector2.Zero;
                }

                float C = _maxLength2 - length2;
                linearError = Math.Max(linearError, -C);
                C           = MathUtils.Clamp(C + Settings.b2_linearSlop, -Settings.b2_maxLinearCorrection, 0.0f);
                float impulse = -_limitMass2 * C;

                Vector2 P2 = -impulse * _u2;
                b2._sweep.c += b2._invMass * P2;
                b2._sweep.a += b2._invI * MathUtils.Cross(r2, P2);

                b2.SynchronizeTransform();
            }

            return(linearError < Settings.b2_linearSlop);
        }
Пример #31
0
        internal override void InitVelocityConstraints(ref TimeStep step)
        {
            Body b1 = _bodyA;
            Body b2 = _bodyB;

            Transform xf1, xf2;

            b1.GetTransform(out xf1);
            b2.GetTransform(out xf2);

            // Compute the effective mass matrix.
            Vector2 r1 = MathUtils.Multiply(ref xf1.R, _localAnchor1 - b1.GetLocalCenter());
            Vector2 r2 = MathUtils.Multiply(ref xf2.R, _localAnchor2 - b2.GetLocalCenter());

            _u = b2._sweep.c + r2 - b1._sweep.c - r1;

            // Handle singularity.
            float length = _u.Length();

            if (length < _length)
            {
                return;
            }

            if (length > Settings.b2_linearSlop)
            {
                _u *= 1.0f / length;
            }
            else
            {
                _u = new Vector2(0.0f, 0.0f);
            }

            float cr1u    = MathUtils.Cross(r1, _u);
            float cr2u    = MathUtils.Cross(r2, _u);
            float invMass = b1._invMass + b1._invI * cr1u * cr1u + b2._invMass + b2._invI * cr2u * cr2u;

            Debug.Assert(invMass > Settings.b2_epsilon);
            _mass = invMass != 0.0f ? 1.0f / invMass : 0.0f;

            if (_frequencyHz > 0.0f)
            {
                float C = length - _length;

                // Frequency
                float omega = 2.0f * Settings.b2_pi * _frequencyHz;

                // Damping coefficient
                float d = 2.0f * _mass * _dampingRatio * omega;

                // Spring stiffness
                float k = _mass * omega * omega;

                // magic formulas
                _gamma = step.dt * (d + step.dt * k);
                _gamma = _gamma != 0.0f ? 1.0f / _gamma : 0.0f;
                _bias  = C * step.dt * k * _gamma;

                _mass = invMass + _gamma;
                _mass = _mass != 0.0f ? 1.0f / _mass : 0.0f;
            }

            if (step.warmStarting)
            {
                // Scale the impulse to support a variable time step.
                _impulse *= step.dtRatio;

                Vector2 P = _impulse * _u;
                b1._linearVelocity  -= b1._invMass * P;
                b1._angularVelocity -= b1._invI * MathUtils.Cross(r1, P);
                b2._linearVelocity  += b2._invMass * P;
                b2._angularVelocity += b2._invI * MathUtils.Cross(r2, P);
            }
            else
            {
                _impulse = 0.0f;
            }
        }
Пример #32
0
	    public void Add(Body body)
	    {
		    Debug.Assert(_bodyCount < _bodyCapacity);
		    body._islandIndex = _bodyCount;
		    _bodies[_bodyCount++] = body;
	    }
Пример #33
0
        /// <summary>
        /// Adds a polygon to a body
        /// </summary>
        /// <param name="body">The body where the polygon should be added</param>
        /// <param name="vertices">The vertices of the polygon</param>
        /// <param name="density">The density of the polygon</param>
        /// <param name="friction">The friction of the polygon</param>
        /// <param name="restitution">The restitution of the polygon</param>
        private void AddPolygonToBody(Body body, Vector2[] vertices, float density, float friction,
                                      float restitution)
        {
            PolygonShape shape = new PolygonShape();
            shape.Set(vertices, vertices.Length);

            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = shape;
            fixtureDef.density = density;
            fixtureDef.friction = friction;
            fixtureDef.restitution = restitution;

            body.CreateFixture(fixtureDef);
        }
Пример #34
0
        /// <summary>
        /// Creates a new motorcycle and a driver into the given Box2D world.
        /// Creates all the parts of the motorcycle and driver and joints them together.
        /// </summary>
        /// <param name="pBikeSpeed">A pointer to the variable that describes the speed of the 
        ///                          motorcycle</param>
        /// <param name="pRotationData">RotationData to provide the information of the rotation
        ///                             of the device</param>
        /// <param name="pWorld">The Box2D world where the bike is created into</param>
        /// <param name="pCamPos">A pointer to the variable that describes the position of the
        ///                       camera</param>
        /// <param name="pContent">The used ContentManager instance</param>
        /// <param name="pSpriteBatch">The used SpriteBatch instance</param>
        public Bike(float []pBikeSpeed, RotationData pRotationData, World pWorld, float[] pCamPos,
                    ContentManager pContent)
        {
            OffTheBike = false;
            camPos = pCamPos;
            world = pWorld;
            content = pContent;
            RotationData = pRotationData;

            bikeSpeed = pBikeSpeed;

            frontWheel = CreateCirclePart("wheel", frontWheelInitPos, 35.0f, 0, 0.1f, 0.9f, 0.2f);
            frontFork = CreateBoxPart("susp_lower_long", frontForkInitPos, 20.53f, 21.33f, 0, 0.8f,
                                      1.0f, 0.2f);
            rearWheel = CreateCirclePart("rearWheel", rearWheelInitPos, 32.0f, 0, 0.4f, 1.0f,
                                         0.2f);
            rearFork = CreateBoxPart("rearFork", rearForkInitPos, 64.0f, 17.0f, rearForkInitRot,
                                     0.5f, 1.0f, 0.2f);
            bikeBody = CreateBikeBody(bikeBodyInitPos, bikeBodyInitRot, 0.5f, 1.0f, 0.2f);

            RevoluteJointDef motorDef = new RevoluteJointDef();
            motorDef.Initialize(rearWheel, rearFork, rearWheel.GetWorldCenter());
            motorDef.maxMotorTorque = 2.0f;
            motorDef.enableMotor = true;
            motor = (RevoluteJoint)world.CreateJoint(motorDef);

            RevoluteJointDef rearForkBodyDef = new RevoluteJointDef();
            Vector2 anchor = rearFork.GetWorldCenter();
            anchor.X += (32.0f / Level.FACTOR);
            anchor.Y += (13.5f / Level.FACTOR);
            rearForkBodyDef.Initialize(rearFork, bikeBody, anchor);
            rearForkBodyDef.bodyA = rearFork;
            rearForkBodyDef.bodyB = bikeBody;
            rearForkBodyDef.maxMotorTorque = 300.0f;
            world.CreateJoint(rearForkBodyDef);

            RevoluteJointDef frontWheelJointDef = new RevoluteJointDef();
            frontWheelJointDef.Initialize(frontWheel, frontFork, frontWheel.GetWorldCenter());
            frontWheelJointDef.maxMotorTorque = 300.0f;
            world.CreateJoint(frontWheelJointDef);

            DistanceJointDef frontSuspToBikeDef = new DistanceJointDef();
            frontSuspToBikeDef.Initialize(bikeBody, frontFork,
                                          frontFork.GetWorldCenter() + new Vector2(0, 0.4f),
                                          frontFork.GetWorldCenter());
            frontSuspToBikeDef.frequencyHz = 4.0f;
            frontSuspToBikeDef.dampingRatio = 0.1f;
            frontSuspToBikeDef.collideConnected = true;
            world.CreateJoint(frontSuspToBikeDef);

            DistanceJointDef rearForkDistanceDef = new DistanceJointDef();
            rearForkDistanceDef.Initialize(bikeBody, rearFork,
                                           rearFork.GetWorldCenter() + new Vector2(0, 0.4f),
                                           rearFork.GetWorldCenter());
            rearForkDistanceDef.frequencyHz = 7.0f;
            rearForkDistanceDef.dampingRatio = 0.1f;
            rearForkDistanceDef.collideConnected = true;
            world.CreateJoint(rearForkDistanceDef);

            PrismaticJointDef fSuspBikePrismaticDef = new PrismaticJointDef();
            fSuspBikePrismaticDef.Initialize(bikeBody, frontFork, bikeBody.GetWorldCenter(),
                                             new Vector2(0, 1));
            fSuspBikePrismaticDef.enableLimit = true;
            fSuspBikePrismaticDef.lowerTranslation = -0.2f;
            fSuspBikePrismaticDef.upperTranslation = 0.2f;
            fSuspBikePrismaticDef.collideConnected = true;
            world.CreateJoint(fSuspBikePrismaticDef);

            humanBody = CreateBoxPart("human", humanBodyInitPos, 17.0f, 64.0f, 0, 0.1f, 1.0f,
                                      0.2f);
            head = CreateBoxPart("head", headInitPos, 38.4f, 29.9f, headInitRot, 0.1f, 1.0f,
                                 0.2f);
            hand = CreateBoxPart("hand", handInitPos, 34.13f, 8.53f, handInitRot, 0.1f, 1.0f,
                                 0.2f);
            arm = CreateBoxPart("arm", armInitPos, 42.67f, 8.53f, armInitRot, 0.1f, 1.0f, 0.2f);

            WeldJointDef headToHumanDef = new WeldJointDef();
            headToHumanDef.Initialize(head, humanBody, head.GetWorldCenter());
            world.CreateJoint(headToHumanDef);

            RevoluteJointDef humanToBikeDef = new RevoluteJointDef();
            anchor = humanBody.GetWorldCenter();
            anchor.Y += (30.0f / Level.FACTOR);
            humanToBikeDef.Initialize(humanBody, bikeBody, anchor);
            humanToBikeDef.maxMotorTorque = 300.0f;
            humanToBike = world.CreateJoint(humanToBikeDef);

            RevoluteJointDef humanToArmDef = new RevoluteJointDef();
            anchor = arm.GetWorldPoint(new Vector2(-21.33f / Level.FACTOR, 4.26f / Level.FACTOR));
            humanToArmDef.Initialize(humanBody, arm, anchor);
            humanToArmDef.maxMotorTorque = 300.0f;
            world.CreateJoint(humanToArmDef);

            RevoluteJointDef armToHandDef = new RevoluteJointDef();
            anchor = arm.GetWorldPoint(new Vector2(21.33f / Level.FACTOR, 4.26f / Level.FACTOR));
            armToHandDef.Initialize(arm, hand, anchor);
            armToHandDef.maxMotorTorque = 300.0f;
            world.CreateJoint(armToHandDef);

            RevoluteJointDef handToBikeDef = new RevoluteJointDef();
            anchor = hand.GetWorldPoint(new Vector2(17.06f / Level.FACTOR, 4.26f / Level.FACTOR));
            handToBikeDef.Initialize(hand, bikeBody, anchor);
            handToBikeDef.maxMotorTorque = 300.0f;
            handToBike = world.CreateJoint(handToBikeDef);

            DistanceJointDef armToBikeDef = new DistanceJointDef();
            armToBikeDef.Initialize(hand, bikeBody,
                                    hand.GetWorldPoint(new Vector2(-17.00f / Level.FACTOR,
                                                       4.26f / Level.FACTOR)),
                                    bikeBody.GetWorldCenter());
            armToBikeDef.length = 40.0f / Level.FACTOR;
            armToBikeDef.frequencyHz = 10.0f;
            armToBikeDef.dampingRatio = 1.0f;
            armToBikeDef.collideConnected = true;
            armToBike = world.CreateJoint(armToBikeDef);
        }
Пример #35
0
        internal override void InitVelocityConstraints(ref TimeStep step)
        {
            Body b1 = _bodyA;
            Body b2 = _bodyB;

            Transform xf1, xf2;

            b1.GetTransform(out xf1);
            b2.GetTransform(out xf2);

            Vector2 r1 = MathUtils.Multiply(ref xf1.R, _localAnchor1 - b1.GetLocalCenter());
            Vector2 r2 = MathUtils.Multiply(ref xf2.R, _localAnchor2 - b2.GetLocalCenter());

            Vector2 p1 = b1._sweep.c + r1;
            Vector2 p2 = b2._sweep.c + r2;

            Vector2 s1 = _groundAnchor1;
            Vector2 s2 = _groundAnchor2;

            // Get the pulley axes.
            _u1 = p1 - s1;
            _u2 = p2 - s2;

            float length1 = _u1.Length();
            float length2 = _u2.Length();

            if (length1 > Settings.b2_linearSlop)
            {
                _u1 *= 1.0f / length1;
            }
            else
            {
                _u1 = Vector2.Zero;
            }

            if (length2 > Settings.b2_linearSlop)
            {
                _u2 *= 1.0f / length2;
            }
            else
            {
                _u2 = Vector2.Zero;
            }

            float C = _ant - length1 - _ratio * length2;

            if (C > 0.0f)
            {
                _state   = LimitState.Inactive;
                _impulse = 0.0f;
            }
            else
            {
                _state = LimitState.AtUpper;
            }

            if (length1 < _maxLength1)
            {
                _limitState1   = LimitState.Inactive;
                _limitImpulse1 = 0.0f;
            }
            else
            {
                _limitState1 = LimitState.AtUpper;
            }

            if (length2 < _maxLength2)
            {
                _limitState2   = LimitState.Inactive;
                _limitImpulse2 = 0.0f;
            }
            else
            {
                _limitState2 = LimitState.AtUpper;
            }

            // Compute effective mass.
            float cr1u1 = MathUtils.Cross(r1, _u1);
            float cr2u2 = MathUtils.Cross(r2, _u2);

            _limitMass1 = b1._invMass + b1._invI * cr1u1 * cr1u1;
            _limitMass2 = b2._invMass + b2._invI * cr2u2 * cr2u2;
            _pulleyMass = _limitMass1 + _ratio * _ratio * _limitMass2;
            Debug.Assert(_limitMass1 > Settings.b2_epsilon);
            Debug.Assert(_limitMass2 > Settings.b2_epsilon);
            Debug.Assert(_pulleyMass > Settings.b2_epsilon);
            _limitMass1 = 1.0f / _limitMass1;
            _limitMass2 = 1.0f / _limitMass2;
            _pulleyMass = 1.0f / _pulleyMass;

            if (step.warmStarting)
            {
                // Scale impulses to support variable time steps.
                _impulse       *= step.dtRatio;
                _limitImpulse1 *= step.dtRatio;
                _limitImpulse2 *= step.dtRatio;

                // Warm starting.
                Vector2 P1 = -(_impulse + _limitImpulse1) * _u1;
                Vector2 P2 = (-_ratio * _impulse - _limitImpulse2) * _u2;
                b1._linearVelocity  += b1._invMass * P1;
                b1._angularVelocity += b1._invI * MathUtils.Cross(r1, P1);
                b2._linearVelocity  += b2._invMass * P2;
                b2._angularVelocity += b2._invI * MathUtils.Cross(r2, P2);
            }
            else
            {
                _impulse       = 0.0f;
                _limitImpulse1 = 0.0f;
                _limitImpulse2 = 0.0f;
            }
        }
Пример #36
0
 /// <summary>
 /// Call this to put a message back to its default state.
 /// </summary>
 public override void Reset()
 {
     mBody_Out = null;
 }
Пример #37
0
        internal override void InitVelocityConstraints(ref TimeStep step)
        {
            Body b = _bodyB;

            float mass = b.GetMass();

            // Frequency
            float omega = 2.0f * Settings.b2_pi * _frequencyHz;

            // Damping coefficient
            float d = 2.0f * mass * _dampingRatio * omega;

            // Spring stiffness
            float k = mass * (omega * omega);

            // magic formulas
            // gamma has units of inverse mass.
            // beta has units of inverse time.
            Debug.Assert(d + step.dt * k > Settings.b2_epsilon);

            _gamma = step.dt * (d + step.dt * k);
            if (_gamma != 0.0f)
            {
                _gamma = 1.0f / _gamma;
            }

            _beta = step.dt * k * _gamma;

            // Compute the effective mass matrix.
            Transform xf1;

            b.GetTransform(out xf1);
            Vector2 r = MathUtils.Multiply(ref xf1.R, _localAnchor - b.GetLocalCenter());

            // K    = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)]
            //      = [1/m1+1/m2     0    ] + invI1 * [r1.Y*r1.Y -r1.X*r1.Y] + invI2 * [r1.Y*r1.Y -r1.X*r1.Y]
            //        [    0     1/m1+1/m2]           [-r1.X*r1.Y r1.X*r1.X]           [-r1.X*r1.Y r1.X*r1.X]
            float invMass = b._invMass;
            float invI    = b._invI;

            Mat22 K1 = new Mat22(new Vector2(invMass, 0.0f), new Vector2(0.0f, invMass));
            Mat22 K2 = new Mat22(new Vector2(invI * r.Y * r.Y, -invI * r.X * r.Y), new Vector2(-invI * r.X * r.Y, invI * r.X * r.X));

            Mat22 K;

            Mat22.Add(ref K1, ref K2, out K);

            K.col1.X += _gamma;
            K.col2.Y += _gamma;

            _mass = K.GetInverse();

            _C = b._sweep.c + r - _target;

            // Cheat with some damping
            b._angularVelocity *= 0.98f;

            // Warm starting.
            _impulse           *= step.dtRatio;
            b._linearVelocity  += invMass * _impulse;
            b._angularVelocity += invI * MathUtils.Cross(r, _impulse);
        }
Пример #38
0
        protected Joint(JointDef def)
        {
            Debug.Assert(def.bodyA != def.bodyB);

            _type = def.type;
            _bodyA = def.bodyA;
            _bodyB = def.bodyB;
            _collideConnected = def.collideConnected;
            _userData = def.userData;

            _edgeA = new JointEdge();
            _edgeB = new JointEdge();
        }
Пример #39
0
        // Advance a dynamic body to its first time of contact
        // and adjust the position to ensure clearance.
        void SolveTOI(Body body)
        {
            // Find the minimum contact.
            Contact toiContact = null;
            float   toi        = 1.0f;
            Body    toiOther   = null;
            bool    found;
            int     count;
            int     iter = 0;

            bool bullet = body.IsBullet;

            // Iterate until all contacts agree on the minimum TOI. We have
            // to iterate because the TOI algorithm may skip some intermediate
            // collisions when objects rotate through each other.
            do
            {
                count = 0;
                found = false;
                for (ContactEdge ce = body._contactList; ce != null; ce = ce.Next)
                {
                    if (ce.Contact == toiContact)
                    {
                        continue;
                    }

                    Body     other = ce.Other;
                    BodyType type  = other.GetType();

                    // Only bullets perform TOI with dynamic bodies.
                    if (bullet == true)
                    {
                        // Bullets only perform TOI with bodies that have their TOI resolved.
                        if ((other._flags & BodyFlags.Toi) == 0)
                        {
                            continue;
                        }

                        // No repeated hits on non-static bodies
                        if (type != BodyType.Static && (ce.Contact._flags & ContactFlags.BulletHit) != 0)
                        {
                            continue;
                        }
                    }
                    else if (type == BodyType.Dynamic)
                    {
                        continue;
                    }

                    // Check for a disabled contact.
                    Contact contact = ce.Contact;
                    if (contact.IsEnabled() == false)
                    {
                        continue;
                    }

                    // Prevent infinite looping.
                    if (contact._toiCount > 10)
                    {
                        continue;
                    }

                    Fixture fixtureA = contact._fixtureA;
                    Fixture fixtureB = contact._fixtureB;
                    int     indexA   = contact._indexA;
                    int     indexB   = contact._indexB;

                    // Cull sensors.
                    if (fixtureA.IsSensor() || fixtureB.IsSensor())
                    {
                        continue;
                    }

                    Body bodyA = fixtureA._body;
                    Body bodyB = fixtureB._body;

                    // Compute the time of impact in interval [0, minTOI]
                    TOIInput input = new TOIInput();
                    input.proxyA.Set(fixtureA.GetShape(), indexA);
                    input.proxyB.Set(fixtureB.GetShape(), indexB);
                    input.sweepA = bodyA._sweep;
                    input.sweepB = bodyB._sweep;
                    input.tMax   = toi;

                    TOIOutput output;
                    TimeOfImpact.CalculateTimeOfImpact(out output, ref input);

                    if (output.State == TOIOutputState.Touching && output.t < toi)
                    {
                        toiContact = contact;
                        toi        = output.t;
                        toiOther   = other;
                        found      = true;
                    }

                    ++count;
                }

                ++iter;
            } while (found && count > 1 && iter < 50);

            if (toiContact == null)
            {
                body.Advance(1.0f);
                return;
            }

            Sweep backup = body._sweep;

            body.Advance(toi);
            toiContact.Update(_contactManager.ContactListener);
            if (toiContact.IsEnabled() == false)
            {
                // Contact disabled. Backup and recurse.
                body._sweep = backup;
                SolveTOI(body);
            }

            ++toiContact._toiCount;

            // Update all the valid contacts on this body and build a contact island.
            count = 0;
            for (ContactEdge ce = body._contactList; (ce != null) && (count < Settings.b2_maxTOIContacts); ce = ce.Next)
            {
                Body     other = ce.Other;
                BodyType type  = other.GetType();

                // Only perform correction with static bodies, so the
                // body won't get pushed out of the world.
                if (type == BodyType.Dynamic)
                {
                    continue;
                }

                // Check for a disabled contact.
                Contact contact = ce.Contact;
                if (contact.IsEnabled() == false)
                {
                    continue;
                }

                Fixture fixtureA = contact._fixtureA;
                Fixture fixtureB = contact._fixtureB;

                // Cull sensors.
                if (fixtureA.IsSensor() || fixtureB.IsSensor())
                {
                    continue;
                }

                // The contact likely has some new contact points. The listener
                // gives the user a chance to disable the contact.
                if (contact != toiContact)
                {
                    contact.Update(_contactManager.ContactListener);
                }

                // Did the user disable the contact?
                if (contact.IsEnabled() == false)
                {
                    // Skip this contact.
                    continue;
                }

                if (contact.IsTouching() == false)
                {
                    continue;
                }

                _toiContacts[count] = contact;
                ++count;
            }

            // Reduce the TOI body's overlap with the contact island.
            _toiSolver.Initialize(_toiContacts, count, body);

            float k_toiBaumgarte = 0.75f;

            //bool solved = false;
            for (int i = 0; i < 20; ++i)
            {
                bool contactsOkay = _toiSolver.Solve(k_toiBaumgarte);
                if (contactsOkay)
                {
                    //solved = true;
                    break;
                }
            }

            if (toiOther.GetType() != BodyType.Static)
            {
                toiContact._flags |= ContactFlags.BulletHit;
            }
        }
Пример #40
0
        /// <summary> Create a joint to rain bodies together. No reference to the definition
        /// is retained. This may cause the connected bodies to cease colliding.
        /// </summary> <warning> This function is locked during callbacks.
        /// </warning>
        public Joint CreateJoint(JointDef def)
        {
            Debug.Assert(!IsLocked);
            if (IsLocked)
            {
                return(null);
            }

            Joint j = Joint.Create(def);

            // Connect to the world list.
            j._prev = null;
            j._next = _jointList;
            if (_jointList != null)
            {
                _jointList._prev = j;
            }
            _jointList = j;
            ++_jointCount;

            // Connect to the bodies' doubly linked lists.
            j._edgeA.Joint = j;
            j._edgeA.Other = j._bodyB;
            j._edgeA.Prev  = null;
            j._edgeA.Next  = j._bodyA._jointList;

            if (j._bodyA._jointList != null)
            {
                j._bodyA._jointList.Prev = j._edgeA;
            }

            j._bodyA._jointList = j._edgeA;

            j._edgeB.Joint = j;
            j._edgeB.Other = j._bodyA;
            j._edgeB.Prev  = null;
            j._edgeB.Next  = j._bodyB._jointList;

            if (j._bodyB._jointList != null)
            {
                j._bodyB._jointList.Prev = j._edgeB;
            }

            j._bodyB._jointList = j._edgeB;

            Body bodyA = def.bodyA;
            Body bodyB = def.bodyB;

            bool staticA = bodyA.GetType() == BodyType.Static;
            bool staticB = bodyB.GetType() == BodyType.Static;

            // If the joint prevents collisions, then flag any contacts for filtering.
            if (def.collideConnected == false)
            {
                ContactEdge edge = bodyB.GetContactList();
                while (edge != null)
                {
                    if (edge.Other == bodyA)
                    {
                        // Flag the contact for filtering at the next time step (where either
                        // body is awake).
                        edge.Contact.FlagForFiltering();
                    }

                    edge = edge.Next;
                }
            }

            // Note: creating a joint doesn't wake the bodies.

            return(j);
        }
Пример #41
0
        void Solve(ref TimeStep step)
        {
            // Size the island for the worst case.
            _island.Reset(_bodyCount,
                          _contactManager._contactCount,
                          _jointCount,
                          _contactManager.ContactListener);

            // Clear all the island flags.
            for (Body b = _bodyList; b != null; b = b._next)
            {
                b._flags &= ~BodyFlags.Island;
            }
            for (Contact c = _contactManager._contactList; c != null; c = c._next)
            {
                c._flags &= ~ContactFlags.Island;
            }
            for (Joint j = _jointList; j != null; j = j._next)
            {
                j._islandFlag = false;
            }

            // Build and simulate all awake islands.
            int stackSize = _bodyCount;

            if (stackSize > stack.Length)
            {
                stack = new Body[Math.Max(stack.Length * 2, stackSize)];
            }

            for (Body seed = _bodyList; seed != null; seed = seed._next)
            {
                if ((seed._flags & (BodyFlags.Island)) != BodyFlags.None)
                {
                    continue;
                }

                if (seed.IsAwake() == false || seed.IsActive() == false)
                {
                    continue;
                }

                // The seed can be dynamic or kinematic.
                if (seed.GetType() == BodyType.Static)
                {
                    continue;
                }

                // Reset island and stack.
                _island.Clear();
                int stackCount = 0;
                stack[stackCount++] = seed;
                seed._flags        |= BodyFlags.Island;

                // Perform a depth first search (DFS) on the raint graph.
                while (stackCount > 0)
                {
                    // Grab the next body off the stack and add it to the island.
                    Body b = stack[--stackCount];
                    Debug.Assert(b.IsActive() == true);
                    _island.Add(b);

                    // Make sure the body is awake.
                    b.SetAwake(true);

                    // To keep islands as small as possible, we don't
                    // propagate islands across static bodies.
                    if (b.GetType() == BodyType.Static)
                    {
                        continue;
                    }

                    // Search all contacts connected to this body.
                    for (ContactEdge ce = b._contactList; ce != null; ce = ce.Next)
                    {
                        Contact contact = ce.Contact;

                        // Has this contact already been added to an island?
                        if ((contact._flags & ContactFlags.Island) != ContactFlags.None)
                        {
                            continue;
                        }

                        // Is this contact solid and touching?
                        if (!ce.Contact.IsEnabled() || !ce.Contact.IsTouching())
                        {
                            continue;
                        }

                        // Skip sensors.
                        bool sensorA = contact._fixtureA._isSensor;
                        bool sensorB = contact._fixtureB._isSensor;
                        if (sensorA || sensorB)
                        {
                            continue;
                        }

                        _island.Add(contact);
                        contact._flags |= ContactFlags.Island;

                        Body other = ce.Other;

                        // Was the other body already added to this island?
                        if ((other._flags & BodyFlags.Island) != BodyFlags.None)
                        {
                            continue;
                        }

                        Debug.Assert(stackCount < stackSize);
                        stack[stackCount++] = other;
                        other._flags       |= BodyFlags.Island;
                    }

                    // Search all joints connect to this body.
                    for (JointEdge je = b._jointList; je != null; je = je.Next)
                    {
                        if (je.Joint._islandFlag == true)
                        {
                            continue;
                        }

                        Body other = je.Other;

                        // Don't simulate joints connected to inactive bodies.
                        if (other.IsActive() == false)
                        {
                            continue;
                        }

                        _island.Add(je.Joint);
                        je.Joint._islandFlag = true;

                        if ((other._flags & BodyFlags.Island) != BodyFlags.None)
                        {
                            continue;
                        }

                        Debug.Assert(stackCount < stackSize);
                        stack[stackCount++] = other;
                        other._flags       |= BodyFlags.Island;
                    }
                }

                _island.Solve(ref step, Gravity, _allowSleep);

                // Post solve cleanup.
                for (int i = 0; i < _island._bodyCount; ++i)
                {
                    // Allow static bodies to participate in other islands.
                    Body b = _island._bodies[i];
                    if (b.GetType() == BodyType.Static)
                    {
                        b._flags &= ~BodyFlags.Island;
                    }
                }
            }

            // Synchronize fixtures, check for out of range bodies.
            for (Body b = _bodyList; b != null; b = b.GetNext())
            {
                // If a body was not in an island then it did not move.
                if ((b._flags & BodyFlags.Island) != BodyFlags.Island)
                {
                    continue;
                }

                if (b.GetType() == BodyType.Static)
                {
                    continue;
                }

                // Update fixtures (for broad-phase).
                b.SynchronizeFixtures();
            }

            // Look for new contacts.
            _contactManager.FindNewContacts();
        }
Пример #42
0
        /// <summary> Call this to draw shapes and other debug draw data.
        /// </summary>
        public void DrawDebugData()
        {
            if (DebugDraw == null)
            {
                return;
            }

            DebugDrawFlags flags = DebugDraw.Flags;

            if ((flags & DebugDrawFlags.Shape) == DebugDrawFlags.Shape)
            {
                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    Transform xf;
                    b.GetTransform(out xf);
                    for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext())
                    {
                        if (b.IsActive() == false)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.5f, 0.3f));
                        }
                        else if (b.GetType() == BodyType.Static)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.9f, 0.5f));
                        }
                        else if (b.GetType() == BodyType.Kinematic)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.5f, 0.9f));
                        }
                        else if (b.IsAwake() == false)
                        {
                            DrawShape(f, xf, new Color(0.6f, 0.6f, 0.6f));
                        }
                        else
                        {
                            DrawShape(f, xf, new Color(0.9f, 0.7f, 0.7f));
                        }
                    }
                }
            }

            if ((flags & DebugDrawFlags.Joint) == DebugDrawFlags.Joint)
            {
                for (Joint j = _jointList; j != null; j = j.GetNext())
                {
                    DrawJoint(j);
                }
            }

            if ((flags & DebugDrawFlags.Pair) == DebugDrawFlags.Pair)
            {
                Color color = new Color(0.3f, 0.9f, 0.9f);
                for (Contact c = _contactManager._contactList; c != null; c = c.GetNext())
                {
                    /*
                     * Fixture fixtureA = c.GetFixtureA();
                     * Fixture fixtureB = c.GetFixtureB();
                     *
                     * AABB aabbA;
                     * AABB aabbB;
                     * fixtureA.GetAABB(out aabbA);
                     * fixtureB.GetAABB(out aabbB);
                     *
                     * Vector2 cA = aabbA.GetCenter();
                     * Vector2 cB = aabbB.GetCenter();
                     *
                     * DebugDraw.DrawSegment(cA, cB, color);
                     */
                }
            }

            if ((flags & DebugDrawFlags.AABB) == DebugDrawFlags.AABB)
            {
                Color      color = new Color(0.9f, 0.3f, 0.9f);
                BroadPhase bp    = _contactManager._broadPhase;

                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    if (b.IsActive() == false)
                    {
                        continue;
                    }

                    for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext())
                    {
                        for (int i = 0; i < f._proxyCount; ++i)
                        {
                            FixtureProxy proxy = f._proxies[i];
                            AABB         aabb;
                            bp.GetFatAABB(proxy.proxyId, out aabb);
                            FixedArray8 <Vector2> vs = new FixedArray8 <Vector2>();
                            vs[0] = new Vector2(aabb.lowerBound.X, aabb.lowerBound.Y);
                            vs[1] = new Vector2(aabb.upperBound.X, aabb.lowerBound.Y);
                            vs[2] = new Vector2(aabb.upperBound.X, aabb.upperBound.Y);
                            vs[3] = new Vector2(aabb.lowerBound.X, aabb.upperBound.Y);

                            DebugDraw.DrawPolygon(ref vs, 4, color);
                        }
                    }
                }
            }

            if ((flags & DebugDrawFlags.CenterOfMass) == DebugDrawFlags.CenterOfMass)
            {
                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    Transform xf;
                    b.GetTransform(out xf);
                    xf.Position = b.GetWorldCenter();
                    DebugDraw.DrawTransform(ref xf);
                }
            }
        }
Пример #43
0
	    public void Solve(ref TimeStep step, Vector2 gravity, bool allowSleep)
        {
            // Integrate velocities and apply damping.
	        for (int i = 0; i < _bodyCount; ++i)
	        {
		        Body b = _bodies[i];

                if (b.GetType() != BodyType.Dynamic)
                {
                    continue;
                }

		        // Integrate velocities.
		        b._linearVelocity += step.dt * (gravity + b._invMass * b._force);
		        b._angularVelocity += step.dt * b._invI * b._torque;

		        // Apply damping.
		        // ODE: dv/dt + c * v = 0
		        // Solution: v(t) = v0 * exp(-c * t)
		        // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
		        // v2 = exp(-c * dt) * v1
		        // Taylor expansion:
		        // v2 = (1.0f - c * dt) * v1
		        b._linearVelocity *= MathUtils.Clamp(1.0f - step.dt * b._linearDamping, 0.0f, 1.0f);
		        b._angularVelocity *= MathUtils.Clamp(1.0f - step.dt * b._angularDamping, 0.0f, 1.0f);
	        }

            // Partition contacts so that contacts with static bodies are solved last.
	        int i1 = -1;
	        for (int i2 = 0; i2 < _contactCount; ++i2)
	        {
		        Fixture fixtureA = _contacts[i2].GetFixtureA();
		        Fixture fixtureB = _contacts[i2].GetFixtureB();
		        Body bodyA = fixtureA.GetBody();
		        Body bodyB = fixtureB.GetBody();
                bool nonStatic = bodyA.GetType() != BodyType.Static && bodyB.GetType() != BodyType.Static;
		        if (nonStatic)
		        {
			        ++i1;
			        //b2Swap(_contacts[i1], _contacts[i2]);
                    Contact temp = _contacts[i1];
                    _contacts[i1] = _contacts[i2];
                    _contacts[i2] = temp;
		        }
	        }

	        // Initialize velocity constraints.
            _contactSolver.Reset(_contacts, _contactCount, step.dtRatio);
	        _contactSolver.WarmStart();

	        for (int i = 0; i < _jointCount; ++i)
	        {
		        _joints[i].InitVelocityConstraints(ref step);
	        }

	        // Solve velocity constraints.
	        for (int i = 0; i < step.velocityIterations; ++i)
	        {
		        for (int j = 0; j < _jointCount; ++j)
		        {
			        _joints[j].SolveVelocityConstraints(ref step);
		        }

                _contactSolver.SolveVelocityConstraints();
	        }

	        // Post-solve (store impulses for warm starting).
            _contactSolver.StoreImpulses();

	        // Integrate positions.
	        for (int i = 0; i < _bodyCount; ++i)
	        {
		        Body b = _bodies[i];

                if (b.GetType() == BodyType.Static)
                {
                    continue;
                }

		        // Check for large velocities.
		        Vector2 translation = step.dt * b._linearVelocity;
		        if (Vector2.Dot(translation, translation) > Settings.b2_maxTranslationSquared)
		        {
			        float ratio = Settings.b2_maxTranslation / translation.Length();
                    b._linearVelocity *= ratio;
		        }

		        float rotation = step.dt * b._angularVelocity;
		        if (rotation * rotation > Settings.b2_maxRotationSquared)
		        {
                    float ratio = Settings.b2_maxRotation / Math.Abs(rotation);
                    b._angularVelocity *= ratio;
		        }

		        // Store positions for continuous collision.
		        b._sweep.c0 = b._sweep.c;
		        b._sweep.a0 = b._sweep.a;

		        // Integrate
		        b._sweep.c += step.dt * b._linearVelocity;
		        b._sweep.a += step.dt * b._angularVelocity;

		        // Compute new transform
		        b.SynchronizeTransform();

		        // Note: shapes are synchronized later.
	        }

	        // Iterate over constraints.
            for (int i = 0; i < step.positionIterations; ++i)
	        {
                bool contactsOkay = _contactSolver.SolvePositionConstraints(Settings.b2_contactBaumgarte);

		        bool jointsOkay = true;
		        for (int j = 0; j < _jointCount; ++j)
		        {
			        bool jointOkay = _joints[j].SolvePositionConstraints(Settings.b2_contactBaumgarte);
			        jointsOkay = jointsOkay && jointOkay;
		        }

		        if (contactsOkay && jointsOkay)
		        {
			        // Exit early if the position errors are small.
			        break;
		        }
	        }

            Report(_contactSolver._constraints);

	        if (allowSleep)
	        {
		        float minSleepTime = Settings.b2_maxFloat;

		        const float linTolSqr = Settings.b2_linearSleepTolerance * Settings.b2_linearSleepTolerance;
		        const float angTolSqr = Settings.b2_angularSleepTolerance * Settings.b2_angularSleepTolerance;

		        for (int i = 0; i < _bodyCount; ++i)
		        {
			        Body b = _bodies[i];
			        if (b.GetType() == BodyType.Static)
			        {
				        continue;
			        }

			        if ((b._flags & BodyFlags.AutoSleep) == 0)
			        {
				        b._sleepTime = 0.0f;
				        minSleepTime = 0.0f;
			        }

			        if ((b._flags & BodyFlags.AutoSleep) == 0 ||
				        b._angularVelocity * b._angularVelocity > angTolSqr ||
				        Vector2.Dot(b._linearVelocity, b._linearVelocity) > linTolSqr)
			        {
				        b._sleepTime = 0.0f;
				        minSleepTime = 0.0f;
			        }
			        else
			        {
				        b._sleepTime += step.dt;
				        minSleepTime = Math.Min(minSleepTime, b._sleepTime);
			        }
		        }

		        if (minSleepTime >= Settings.b2_timeToSleep)
		        {
			        for (int i = 0; i < _bodyCount; ++i)
			        {
				        Body b = _bodies[i];
                        b.SetAwake(false);
			        }
		        }
	        }
        }
        public Atom(Symbol symbol, Vector2 position, GameContent gameContent, World world)
        {
            this.gameContent = gameContent;
            this.world = world;

            if (symbol == Symbol.Ra) eye = EyeState.Angry;

            this.symbol = symbol;
            this.symbolStr = symbol.ToString();
            symbolCenter = gameContent.symbolFont.MeasureString(this.symbolStr);
            symbolCenter.X *= 0.5f;
            symbolCenter.Y *= 0.92f;

            bondsLeft = (int)symbol;

            BodyDef bd = new BodyDef();
            bd.type = BodyType.Dynamic;
            bd.position = this.position = position / gameContent.b2Scale;
            bd.bullet = true;
            body = world.CreateBody(bd);
            body.SetUserData(this);

            CircleShape cs = new CircleShape();
            cs._radius = gameContent.atomRadius / gameContent.b2Scale;

            FixtureDef fd = new FixtureDef();
            fd.shape = cs;
            fd.restitution = 0.2f;
            fd.friction = 0.5f;

            fixture = body.CreateFixture(fd);

            electroShockAnimation = new Animation(gameContent.electroShock, 3, 0.1f, true, new Vector2(0.5f, 0.5f));

            radiationSmoke = new RadiationSmoke(gameContent, this);

            // Collide only with Ground but not with itself and bonded Filter
            mouseFilter = new Filter();
            mouseFilter.categoryBits = 0x0002; mouseFilter.maskBits = 0x0001; mouseFilter.groupIndex = -2;

            // Collide with every thing
            atomFilter = new Filter();
            atomFilter.categoryBits = 0x0001; atomFilter.maskBits = 0x0001; atomFilter.groupIndex = 1;

            fixture.SetFilterData(ref atomFilter);

            SetMode(false, false);
        }
Пример #45
0
        // Sequentially solve TOIs for each body. We bring each
        // body to the time of contact and perform some position correction.
        // Time is not conserved.
        void SolveTOI()
        {
            // Prepare all contacts.
            for (Contact c = _contactManager._contactList; c != null; c = c._next)
            {
                // Enable the contact
                c._flags |= ContactFlags.Enabled;

                // Set the number of TOI events for this contact to zero.
                c._toiCount = 0;
            }

            // Initialize the TOI flag.
            for (Body body = _bodyList; body != null; body = body._next)
            {
                // Kinematic, and static bodies will not be affected by the TOI event.
                // If a body was not in an island then it did not move.
                if ((body._flags & BodyFlags.Island) == 0 || body.GetType() == BodyType.Kinematic || body.GetType() == BodyType.Static)
                {
                    body._flags |= BodyFlags.Toi;
                }
                else
                {
                    body._flags &= ~BodyFlags.Toi;
                }
            }

            // Collide non-bullets.
            for (Body body = _bodyList; body != null; body = body._next)
            {
                if ((body._flags & BodyFlags.Toi) != BodyFlags.None)
                {
                    continue;
                }

                if (body.IsBullet == true)
                {
                    continue;
                }

                SolveTOI(body);

                body._flags |= BodyFlags.Toi;
            }

            // Collide bullets.
            for (Body body = _bodyList; body != null; body = body._next)
            {
                if ((body._flags & BodyFlags.Toi) != BodyFlags.None)
                {
                    continue;
                }

                if (body.IsBullet == false)
                {
                    continue;
                }

                SolveTOI(body);

                body._flags |= BodyFlags.Toi;
            }
        }