예제 #1
0
        public void Create(b2Body body, b2FixtureDef def)
        {
            m_userData    = def.userData;
            m_friction    = def.friction;
            m_restitution = def.restitution;

            m_body = body;
            Next   = null;

            m_filter = def.filter;

            m_isSensor = def.isSensor;

            m_shape = def.shape.Clone();

            // Reserve proxy space
            int childCount = m_shape.GetChildCount();

            for (int i = 0; i < childCount; ++i)
            {
                b2FixtureProxy proxy = new b2FixtureProxy();
                proxy.fixture = null;
                proxy.proxyId = b2BroadPhase.e_nullProxy;
                m_proxies.Add(proxy);
            }
            m_proxyCount = 0;

            m_density = def.density;
        }
예제 #2
0
 public void Add(b2Body body)
 {
     Debug.Assert(m_bodyCount < m_bodyCapacity);
     body.IslandIndex      = m_bodyCount;
     m_bodies[m_bodyCount] = body;
     ++m_bodyCount;
 }
예제 #3
0
 public MouseTouch(b2World world, RubeBasicLayer layer)
 {
     parent = layer;
     m_world = world;
     b2BodyDef bodyDef = new b2BodyDef();
     m_groundBody = m_world.CreateBody(bodyDef);
 }
예제 #4
0
        public JumpPad(b2Vec2 JumpImpuls, CCPoint Position, b2World gameWorld)
        {
            this.Texture = new CCTexture2D ("jumppad");
            this.Scale = SpriteScale;
            this.Position = Position;
            this.IsAntialiased = false;

            jumpImpuls = JumpImpuls;
            totalJumps = 0;

            //box2d
            b2BodyDef jumpPadDef = new b2BodyDef ();
            jumpPadDef.type = b2BodyType.b2_kinematicBody;
            jumpPadDef.position = new b2Vec2 ((Position.X + this.ScaledContentSize.Width/2)/PhysicsHandler.pixelPerMeter, (Position.Y + this.ScaledContentSize.Height/4) / PhysicsHandler.pixelPerMeter);
            JumpPadBody = gameWorld.CreateBody (jumpPadDef);

            b2PolygonShape jumpPadShape = new b2PolygonShape ();
            jumpPadShape.SetAsBox ((float)this.ScaledContentSize.Width / PhysicsHandler.pixelPerMeter / 2, (float)this.ScaledContentSize.Height / PhysicsHandler.pixelPerMeter / 4);// /4 weil die hitbox nur die hälfte der textur ist

            b2FixtureDef jumpPadFixture = new b2FixtureDef ();
            jumpPadFixture.shape = jumpPadShape;
            jumpPadFixture.density = 0.0f; //Dichte
            jumpPadFixture.restitution = 0f; //Rückprall
            jumpPadFixture.friction = 0f;
            jumpPadFixture.userData = WorldFixtureData.jumppad;
            JumpPadBody.CreateFixture (jumpPadFixture);
            //
        }
예제 #5
0
        public void Create(b2Body body, b2FixtureDef def)
        {
            UserData    = def.userData;
            Friction    = def.friction;
            Restitution = def.restitution;

            Body = body;
            Next = null;

            m_filter = def.filter;

            m_isSensor = def.isSensor;

            Shape = def.shape.Clone();

            // Reserve proxy space
            int childCount = Shape.GetChildCount();

            m_proxies = b2ArrayPool <b2FixtureProxy> .Create(childCount, true);

            for (int i = 0; i < childCount; ++i)
            {
                m_proxies[i].fixture = null;
                m_proxies[i].proxyId = b2BroadPhase.e_nullProxy;
            }
            m_proxyCount = 0;

            Density = def.density;
        }
예제 #6
0
        public void Dump()
        {
            if ((m_flags & b2WorldType.e_locked) == e_locked)
            {
                return;
            }

            System.Diagnostics.Debug.WriteLine("b2Vec2 g({0:N5}, {0:N5});", m_gravity.x, m_gravity.y);
            System.Diagnostics.Debug.WriteLine("m_world.SetGravity(g);");

            System.Diagnostics.Debug.WriteLine("b2Body* bodies = (b2Body*)b2Alloc({0} * sizeof(b2Body));", m_bodyCount);
            System.Diagnostics.Debug.WriteLine("b2Joint* joints = (b2Joint*)b2Alloc({0} * sizeof(b2Joint));", m_jointCount);
            int i = 0;

            for (b2Body b = m_bodyList; b != null; b = b.Next)
            {
                b.IslandIndex = i;
                b.Dump();
                ++i;
            }

            i = 0;
            for (b2Joint j = m_jointList; j != null; j = j.Next)
            {
                j.Index = i;
                ++i;
            }

            // First pass on joints, skip gear joints.
            for (b2Joint j = m_jointList; j != null; j = j.Next)
            {
                if (j.JointType == b2JointType.e_gearJoint)
                {
                    continue;
                }

                System.Diagnostics.Debug.WriteLine("{");
                j.Dump();
                System.Diagnostics.Debug.WriteLine("}");
            }

            // Second pass on joints, only gear joints.
            for (b2Joint j = m_jointList; j != null; j = j.Next)
            {
                if (j.JointType != b2JointType.e_gearJoint)
                {
                    continue;
                }

                System.Diagnostics.Debug.WriteLine("{");
                j.Dump();
                System.Diagnostics.Debug.WriteLine("}");
            }

            System.Diagnostics.Debug.WriteLine("b2Free(joints);");
            System.Diagnostics.Debug.WriteLine("b2Free(bodies);");
            System.Diagnostics.Debug.WriteLine("joints = null;");
            System.Diagnostics.Debug.WriteLine("bodies = null;");
        }
예제 #7
0
 public void RemoveBody()
 {
     if (body != null)
     {
         body.World.DestroyBody(body);
         body = null;
     }
 }
예제 #8
0
 public void ClearForces()
 {
     for (b2Body body = m_bodyList; body != null; body = body.Next)
     {
         body.Force  = new b2Vec2();
         body.Torque = 0.0f;
     }
 }
예제 #9
0
        public WallJumpManager(b2Body parentJumpBody, float JumpTimeNeeded, float JumpHeight, float JumpWidth)
        {
            jumpBody = parentJumpBody;
            maxTime = JumpTimeNeeded;
            jumpSize = new CCSize (JumpWidth, JumpHeight);

            CurrentJumpingDirection = Direction.Left;
        }
예제 #10
0
 public void Initialize(b2Body b1, b2Body b2,
                             b2Vec2 anchor1, b2Vec2 anchor2)
 {
     BodyA = b1;
     BodyB = b2;
     localAnchorA = BodyA.GetLocalPoint(anchor1);
     localAnchorB = BodyB.GetLocalPoint(anchor2);
     b2Vec2 d = anchor2 - anchor1;
     length = d.Length;
 }
예제 #11
0
        public int CompareTo(object obj)
        {
            b2Body b2 = obj as b2Body;

            if (b2 == null)
            {
                return(-1);
            }
            if (BodyType != b2.BodyType)
            {
                return(BodyType.CompareTo(b2.BodyType));
            }
            return(obj == this ? 0 : -1);
        }
예제 #12
0
        //
        public void SetAllowSleeping(bool flag)
        {
            if (flag == m_allowSleep)
            {
                return;
            }

            m_allowSleep = flag;
            if (m_allowSleep == false)
            {
                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    b.SetAwake(true);
                }
            }
        }
예제 #13
0
        /**
         * the destructor cannot access the allocator (no destructor arguments allowed by C++).
         *  We need separation create/destroy functions from the constructor/destructor because
         */
        public void Create(b2Body body, b2Transform xf, b2FixtureDef def)
        {
            m_userData    = def.userData;
            m_friction    = def.friction;
            m_restitution = def.restitution;

            m_body = body;
            m_next = null;

            m_filter = def.filter.Copy();

            m_isSensor = def.isSensor;

            m_shape = def.shape.Copy();

            m_density = def.density;
        }
예제 #14
0
        protected void CreateBodyWithSpriteAndFixture(b2World world, b2BodyDef bodyDef,
                                                       b2FixtureDef fixtureDef, string spriteName)
        {
            // this is the meat of our class, it creates (OR recreates) the body in the world with the body definition, fixture definition and sprite name

            RemoveBody(); //if remove the body if it already exists
            RemoveSprite(); //if remove the sprite if it already exists

            sprite = new CCSprite(spriteName);
            AddChild(sprite);

            body = world.CreateBody(bodyDef);
            body.UserData = this;

            if (fixtureDef != null)
                body.CreateFixture(fixtureDef);
        }
예제 #15
0
        public Platform(List<CCPoint> platformWaypoints, int platformSpeed, Container gameContainer)
        {
            this.Texture = new CCTexture2D("platform");
            this.Scale = SpriteScale;
            this.IsAntialiased = false;

            this.Position = platformWaypoints [0];
            Waypoints = platformWaypoints;
            speed = platformSpeed;
            //umso geringer der speed umso schneller die platform

            CurrentWaypoint = 0;
            wayToMove = new CCSize (Waypoints [CurrentWaypoint + 1].X - Waypoints [CurrentWaypoint].X, Waypoints [CurrentWaypoint + 1].Y - Waypoints [CurrentWaypoint].Y);

            //box2d
            b2BodyDef platformDef = new b2BodyDef ();
            platformDef.type = b2BodyType.b2_kinematicBody;
            platformDef.position = new b2Vec2 (Waypoints[CurrentWaypoint].X / PhysicsHandler.pixelPerMeter, Waypoints[CurrentWaypoint].Y / PhysicsHandler.pixelPerMeter);
            platformBody = gameContainer.physicsHandler.gameWorld.CreateBody (platformDef);

            b2PolygonShape platformShape = new b2PolygonShape ();
            platformShape.SetAsBox ((float)this.ScaledContentSize.Width / PhysicsHandler.pixelPerMeter / 2, (float)this.ScaledContentSize.Height / PhysicsHandler.pixelPerMeter / 2);

            b2FixtureDef platformFixture = new b2FixtureDef ();
            platformFixture.shape = platformShape;
            platformFixture.density = 0.0f; //Dichte
            platformFixture.restitution = 0f; //Rückprall
            platformFixture.userData = WorldFixtureData.platform;
            platformBody.CreateFixture (platformFixture);
            //

            this.Position = new CCPoint (platformBody.Position.x * PhysicsHandler.pixelPerMeter, platformBody.Position.y * PhysicsHandler.pixelPerMeter);

            progressionX = wayToMove.Width/ (float)speed;
            progressionY =  wayToMove.Height/(float)speed ;
            if (float.IsInfinity (progressionX))
                progressionX = 0;
            if (float.IsInfinity (progressionY))
                progressionY = 0;
            b2Vec2 Velocity = platformBody.LinearVelocity;
            Velocity.y = progressionY;
            Velocity.x = progressionX;
            platformBody.LinearVelocity = Velocity;
        }
예제 #16
0
파일: Mouse.cs 프로젝트: netonjm/Rube.Net
        public void SetJson(string fullpath)
        {
            Console.WriteLine("Full path is: %s", fullpath);

            Nb2dJson json = new Nb2dJson();
            StringBuilder tmp = new StringBuilder();
            m_world = json.ReadFromFile(fullpath, tmp);

            if (m_world != null)
            {
                Console.WriteLine("Loaded JSON ok");
                m_world.SetDebugDraw(m_debugDraw);

                b2BodyDef bodyDef = new b2BodyDef();
                m_groundBody = m_world.CreateBody(bodyDef);
            }
            else
                Console.WriteLine(tmp); //if this warning bothers you, turn off "Typecheck calls to printf/scanf" in the project build settings

        }
예제 #17
0
        public b2Body CreateBody(b2BodyDef def)
        {
            if (IsLocked())
            {
                return(null);
            }

            b2Body b = new b2Body(def, this);

            // Add to world doubly linked list.
            b.Prev = null;
            b.Next = m_bodyList;
            if (m_bodyList != null)
            {
                m_bodyList.Prev = b;
            }
            m_bodyList = b;
            ++m_bodyCount;

            return(b);
        }
예제 #18
0
        public void DrawJoint(b2Joint joint)
        {
            b2Body      bodyA = joint.GetBodyA();
            b2Body      bodyB = joint.GetBodyB();
            b2Transform xf1   = bodyA.Transform;
            b2Transform xf2   = bodyB.Transform;
            b2Vec2      x1    = xf1.p;
            b2Vec2      x2    = xf2.p;
            b2Vec2      p1    = joint.GetAnchorA();
            b2Vec2      p2    = joint.GetAnchorB();

            b2Color color = new b2Color(0.5f, 0.8f, 0.8f);

            switch (joint.JointType)
            {
            case b2JointType.e_distanceJoint:
                m_debugDraw.DrawSegment(p1, p2, color);
                break;

            case b2JointType.e_pulleyJoint:
            {
                b2PulleyJoint pulley = (b2PulleyJoint)joint;
                b2Vec2        s1     = pulley.GetGroundAnchorA();
                b2Vec2        s2     = pulley.GetGroundAnchorB();
                m_debugDraw.DrawSegment(s1, p1, color);
                m_debugDraw.DrawSegment(s2, p2, color);
                m_debugDraw.DrawSegment(s1, s2, color);
            }
            break;

            case b2JointType.e_mouseJoint:
                // don't draw this
                break;

            default:
                m_debugDraw.DrawSegment(x1, p1, color);
                m_debugDraw.DrawSegment(p1, p2, color);
                m_debugDraw.DrawSegment(x2, p2, color);
            }
        }
예제 #19
0
        public virtual bool ShouldCollide(b2Body other)
        {
            // At least one body should be dynamic.
            if (m_type != b2_dynamicBody && other.m_type != b2_dynamicBody)
            {
                return(false);
            }

            // Does a joint prevent collision?
            for (b2JointEdge *jn = m_jointList; jn; jn = jn.next)
            {
                if (jn.other == other)
                {
                    if (jn.joint.m_collideConnected == false)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
예제 #20
0
        public virtual bool ShouldCollide(b2Body other)
        {
            // At least one body should be dynamic.
            if (m_type != b2BodyType.b2_dynamicBody && other.m_type != b2BodyType.b2_dynamicBody)
            {
                return(false);
            }

            // Does a joint prevent collision?
            for (b2JointEdge jn = m_jointList; jn != null; jn = jn.Next)
            {
                if (jn.Other == other)
                {
                    if (jn.Joint.GetCollideConnected() == false)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
예제 #21
0
        public BoxProp(
               b2World b2world,

             double[] size,
             double[] position

            )
        {
            /*
            static rectangle shaped prop
     
                pars:
                size - array [width, height]
                position - array [x, y], in world meters, of center
            */
            this.size = size;

            //initialize body
            var bdef = new b2BodyDef();
            bdef.position = new b2Vec2(position[0], position[1]);
            bdef.angle = 0;
            bdef.fixedRotation = true;
            this.body = b2world.CreateBody(bdef);

            //initialize shape
            var fixdef = new b2FixtureDef();

            var shape = new b2PolygonShape();
            fixdef.shape = shape;

            shape.SetAsBox(this.size[0] / 2, this.size[1] / 2);

            fixdef.restitution = 0.4; //positively bouncy!



            this.body.CreateFixture(fixdef);
        }
예제 #22
0
        public b2World(b2Vec2 gravity)
        {
            m_destructionListener = null;
            m_debugDraw           = null;

            m_bodyList  = null;
            m_jointList = null;

            m_bodyCount  = 0;
            m_jointCount = 0;

            m_warmStarting      = true;
            m_continuousPhysics = true;
            m_subStepping       = false;

            m_stepComplete = true;

            m_allowSleep = true;
            m_gravity    = gravity;

            m_flags = b2WorldFlags.e_clearForces;

            m_inv_dt0 = 0.0f;
        }
예제 #23
0
        public void AddPair(ref b2FixtureProxy proxyA, ref b2FixtureProxy proxyB)
        {
            b2Fixture fixtureA = proxyA.fixture;
            b2Fixture fixtureB = proxyB.fixture;

            int indexA = proxyA.childIndex;
            int indexB = proxyB.childIndex;

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

            // Are the fixtures on the same body?
            if (bodyA == bodyB)
            {
                return;
            }

            // TODO_ERIN use a hash table to remove a potential bottleneck when both
            // bodies have a lot of contacts.
            // Does a contact already exist?
            b2ContactEdge edge = bodyB.ContactList;

            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    b2Fixture fA = edge.Contact.FixtureA;
                    b2Fixture fB = edge.Contact.FixtureB;
                    int       iA = edge.Contact.m_indexA;
                    int       iB = edge.Contact.m_indexB;

                    if (fA == fixtureA && fB == fixtureB && iA == indexA && iB == indexB)
                    {
                        // A contact already exists.
                        return;
                    }

                    if (fA == fixtureB && fB == fixtureA && iA == indexB && iB == indexA)
                    {
                        // A contact already exists.
                        return;
                    }
                }

                edge = edge.Next;
            }



            // Does a joint override collision? Is at least one body dynamic?
            if (!bodyB.ShouldCollide(bodyA))
            {
                return;
            }

            // Check user filtering.
            if (m_contactFilter != null && !m_contactFilter.ShouldCollide(fixtureA, fixtureB))
            {
                return;
            }

            // Call the factory.
            b2Contact c = b2Contact.Create(fixtureA, indexA, fixtureB, indexB);

            if (c == null)
            {
                return;
            }

            // Contact creation may swap fixtures.
            //fixtureA = c.FixtureA;
            //fixtureB = c.FixtureB;
            //indexA = c.m_indexA;
            //indexB = c.m_indexB;
            bodyA = c.FixtureA.Body;
            bodyB = c.FixtureB.Body;

            // Insert into the world.
            c.Prev = null;
            c.Next = m_contactList;
            if (m_contactList != null)
            {
                m_contactList.Prev = c;
            }
            m_contactList = c;

            // Connect to island graph.

            // Connect to body A
            c.NodeA.Contact = c;
            c.NodeA.Other   = bodyB;

            c.NodeA.Prev = null;
            c.NodeA.Next = bodyA.ContactList;
            if (bodyA.ContactList != null)
            {
                bodyA.ContactList.Prev = c.NodeA;
            }
            bodyA.ContactList = c.NodeA;

            // Connect to body B
            c.NodeB.Contact = c;
            c.NodeB.Other   = bodyA;

            c.NodeB.Prev = null;
            c.NodeB.Next = bodyB.ContactList;
            if (bodyB.ContactList != null)
            {
                bodyB.ContactList.Prev = c.NodeB;
            }
            bodyB.ContactList = c.NodeB;

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

            ++m_contactCount;
        }
예제 #24
0
        public void DrawDebugData()
        {
            if (m_debugDraw == null)
            {
                return;
            }

            b2DrawFlags flags = m_debugDraw.GetFlags();

            if (flags & b2DrawFlags.e_shapeBit)
            {
                for (b2Body b = m_bodyList; b; b = b.Next)
                {
                    b2Transform xf = b.Transform;
                    for (b2Fixture f = b.FixtureList; f != null; f = f.Next)
                    {
                        if (b.IsActive() == false)
                        {
                            DrawShape(f, xf, new b2Color(0.5f, 0.5f, 0.3f));
                        }
                        else if (b.GetType() == b2BodyType.b2_staticBody)
                        {
                            DrawShape(f, xf, new b2Color(0.5f, 0.9f, 0.5f));
                        }
                        else if (b.GetType() == b2BodyType.b2_kinematicBody)
                        {
                            DrawShape(f, xf, new b2Color(0.5f, 0.5f, 0.9f));
                        }
                        else if (b.IsAwake() == false)
                        {
                            DrawShape(f, xf, new b2Color(0.6f, 0.6f, 0.6f));
                        }
                        else
                        {
                            DrawShape(f, xf, new b2Color(0.9f, 0.7f, 0.7f));
                        }
                    }
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_jointBit))
            {
                for (b2Joint j = m_jointList; j != null; j = j.GetNext())
                {
                    DrawJoint(j);
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_pairBit))
            {
                b2Color color = new b2Color(0.3f, 0.9f, 0.9f);
                for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
                {
                    //b2Fixture fixtureA = c.GetFixtureA();
                    //b2Fixture fixtureB = c.GetFixtureB();

                    //b2Vec2 cA = fixtureA.GetAABB().GetCenter();
                    //b2Vec2 cB = fixtureB.GetAABB().GetCenter();

                    //m_debugDraw.DrawSegment(cA, cB, color);
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_aabbBit))
            {
                b2Color color(0.9f, 0.3f, 0.9f);

                b2BroadPhase bp = m_contactManager.BroadPhase;

                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    if (b.IsActive() == false)
                    {
                        continue;
                    }

                    for (b2Fixture f = b.FixtureList; f != null; f = f.Next)
                    {
                        for (int i = 0; i < f.ProxyCount; ++i)
                        {
                            b2FixtureProxy proxy = f.Proxies[i];
                            b2AABB         aabb  = bp.GetFatAABB(proxy.proxyId);
                            b2Vec2[]       vs    = new b2Vec2[4];
                            vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
                            vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
                            vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
                            vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);

                            m_debugDraw.DrawPolygon(vs, 4, color);
                        }
                    }
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_centerOfMassBit))
            {
                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    b2Transform xf = b.Transform;
                    xf.p = b.WorldCenter;
                    m_debugDraw.DrawTransform(xf);
                }
            }
        }
예제 #25
0
        /// <summary>
        /// ��һ���ڳ��������һ����̬��bird����
        /// �ڶ�����bird�����ж���
        /// ����������box-2d����������bird�������������
        /// </summary>
        private void AddBird()
        {
            CCSprite bird = CCSprite.spriteWithFile("imgs/bird/bird_01");
            bird.rotation = -15;

            // bird���ж���֡����
            List<CCSpriteFrame> frames = new List<CCSpriteFrame>();

            for (int i = 1; i < 3; i++)
            {
                // ֡��ͼ
                CCTexture2D texture = CCTextureCache.sharedTextureCache().addImage("imgs/bird/bird_0" + i);

                // �������һ�������bug����������õĻ����ͻᲥ�Ų���������
                texture.Name = (uint)i;
                var frame = CCSpriteFrame.frameWithTexture(texture, new CCRect(0, 0, texture.ContentSizeInPixels.width, texture.ContentSizeInPixels.height));
                frames.Add(frame);
            }

            // �����
            CCAnimation marmotShowanimation = CCAnimation.animationWithFrames(frames, 0.1f);
            CCAnimate flyAction = CCAnimate.actionWithAnimation(marmotShowanimation, false);
            flyRepeatAction = CCRepeat.actionWithAction(flyAction, 2);
            flyRepeatAction.tag = 0;
            bird.runAction(flyRepeatAction);

            // �����������ж���һ��body��������λ�ã�����bird��֮��Ӧ
            b2BodyDef ballBodyDef = new b2BodyDef();
            ballBodyDef.type = b2BodyType.b2_dynamicBody;
            ballBodyDef.position = new b2Vec2(AppDelegate.screenSize.width / PTM_RATIO / 2, (float)(AppDelegate.screenSize.height / PTM_RATIO));
            ballBodyDef.userData = bird;
            birdBody = world.CreateBody(ballBodyDef);

            // Ϊbody������״��������һЩ��������
            b2PolygonShape shape = new b2PolygonShape();
            shape.SetAsBox(bird.contentSize.width / 2 / PTM_RATIO, bird.contentSize.height / 2 / PTM_RATIO);
            b2FixtureDef fixtureDef = new b2FixtureDef();
            fixtureDef.shape = shape;
            fixtureDef.density = 500.0f;
            fixtureDef.friction = 0.5f;
            birdBody.CreateFixture(fixtureDef);

            this.addChild(bird);
        }
예제 #26
0
        public void SolveTOI(b2TimeStep subStep, int toiIndexA, int toiIndexB)
        {
            Debug.Assert(toiIndexA < m_bodyCount);
            Debug.Assert(toiIndexB < m_bodyCount);

            // Initialize the body state.
            for (int i = 0; i < m_bodyCount; ++i)
            {
                b2Body b = m_bodies[i];
                m_positions[i].c  = b.Sweep.c;
                m_positions[i].a  = b.Sweep.a;
                m_velocities[i].v = b.LinearVelocity;
                m_velocities[i].w = b.AngularVelocity;
            }

            b2ContactSolverDef contactSolverDef;

            contactSolverDef.contacts   = m_contacts;
            contactSolverDef.count      = m_contactCount;
            contactSolverDef.step       = subStep;
            contactSolverDef.positions  = m_positions;
            contactSolverDef.velocities = m_velocities;
            b2ContactSolver contactSolver = new b2ContactSolver(contactSolverDef);

            // Solve position constraints.
            for (int i = 0; i < subStep.positionIterations; ++i)
            {
                bool contactsOkay = contactSolver.SolveTOIPositionConstraints(toiIndexA, toiIndexB);
                if (contactsOkay)
                {
                    break;
                }
            }

#if false
            // Is the new position really safe?
            for (int i = 0; i < m_contactCount; ++i)
            {
                b2Contact c  = m_contacts[i];
                b2Fixture fA = c.GetFixtureA();
                b2Fixture fB = c.GetFixtureB();

                b2Body bA = fA.Body;
                b2Body bB = fB.Body;

                int indexA = c.GetChildIndexA();
                int indexB = c.GetChildIndexB();

                b2DistanceInput input = new b2DistanceInput();
                input.proxyA.Set(fA.Shape, indexA);
                input.proxyB.Set(fB.Shape, indexB);
                input.transformA = bA.Transform;
                input.transformB = bB.Transform;
                input.useRadii   = false;

                b2DistanceOutput output;
                b2SimplexCache   cache = new b2SimplexCache();
                cache.count = 0;
                output      = b2Distance(cache, input);

                if (output.distance == 0 || cache.count == 3)
                {
                    cache.count += 0;
                }
            }
#endif

            // Leap of faith to new safe state.
            m_bodies[toiIndexA].Sweep.c0 = m_positions[toiIndexA].c;
            m_bodies[toiIndexA].Sweep.a0 = m_positions[toiIndexA].a;
            m_bodies[toiIndexB].Sweep.c0 = m_positions[toiIndexB].c;
            m_bodies[toiIndexB].Sweep.a0 = m_positions[toiIndexB].a;

            // No warm starting is needed for TOI events because warm
            // starting impulses were applied in the discrete solver.
            contactSolver.InitializeVelocityConstraints();

            // Solve velocity constraints.
            for (int i = 0; i < subStep.velocityIterations; ++i)
            {
                contactSolver.SolveVelocityConstraints();
            }

            // Don't store the TOI contact forces for warm starting
            // because they can be quite large.

            float h = subStep.dt;

            // Integrate positions
            for (int i = 0; i < m_bodyCount; ++i)
            {
                b2Vec2 c = m_positions[i].c;
                float  a = m_positions[i].a;
                b2Vec2 v = m_velocities[i].v;
                float  w = m_velocities[i].w;

                // Check for large velocities
                b2Vec2 translation = h * v;
                if (b2Math.b2Dot(translation, translation) > b2Settings.b2_maxTranslationSquared)
                {
                    float ratio = b2Settings.b2_maxTranslation / translation.Length;
                    v *= ratio;
                }

                float rotation = h * w;
                if (rotation * rotation > b2Settings.b2_maxRotationSquared)
                {
                    float ratio = b2Settings.b2_maxRotation / Math.Abs(rotation);
                    w *= ratio;
                }

                // Integrate
                c += h * v;
                a += h * w;

                m_positions[i].c  = c;
                m_positions[i].a  = a;
                m_velocities[i].v = v;
                m_velocities[i].w = w;

                // Sync bodies
                b2Body body = m_bodies[i];
                body.Sweep.c         = c;
                body.Sweep.a         = a;
                body.LinearVelocity  = v;
                body.AngularVelocity = w;
                body.SynchronizeTransform();
            }

            Report(contactSolver.m_velocityConstraints);
        }
예제 #27
0
 public void SetBodyName(b2Body body, String name)
 {
     m_bodyToNameMap.Add(body, name);
 }
예제 #28
0
        // Find TOI contacts and solve them.
        public void SolveTOI(b2TimeStep step)
        {
            b2Island island = new b2Island(2 * b2Settings.b2_maxTOIContacts, b2Settings.b2_maxTOIContacts, 0, m_contactManager.ContactListener);

            if (m_stepComplete)
            {
                for (b2Body b = m_bodyList; b; b = b.Next)
                {
                    b.BodyFlags     &= ~b2Body.e_islandFlag;
                    b.m_sweep.alpha0 = 0.0f;
                }

                for (b2Contact c = m_contactManager.ContactList; c; c = c.Next)
                {
                    // Invalidate TOI
                    c.ContactFlags &= ~(b2ContactType.e_toiFlag | b2ContactType.e_islandFlag);
                    c.m_toiCount    = 0;
                    c.m_toi         = 1.0f;
                }
            }

            // Find TOI events and solve them.
            for (; ;)
            {
                // Find the first TOI.
                b2Contact minContact = null;
                float     minAlpha   = 1.0f;

                for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
                {
                    // Is this contact disabled?
                    if (c.IsEnabled() == false)
                    {
                        continue;
                    }

                    // Prevent excessive sub-stepping.
                    if (c.m_toiCount > b2Settings.b2_maxSubSteps)
                    {
                        continue;
                    }

                    float alpha = 1.0f;
                    if (c.ContactFlags.HasFlag(b2ContactFlags.e_toiFlag))
                    {
                        // This contact has a valid cached TOI.
                        alpha = c.m_toi;
                    }
                    else
                    {
                        b2Fixture fA = c.GetFixtureA();
                        b2Fixture fB = c.GetFixtureB();

                        // Is there a sensor?
                        if (fA.IsSensor || fB.IsSensor)
                        {
                            continue;
                        }

                        b2Body bA = fA.Body;
                        b2Body bB = fB.Body;

                        b2BodyType typeA = bA.BodyType;
                        b2BodyType typeB = bB.BodyType;

                        bool activeA = bA.IsAwake() && typeA != b2BodyType.b2_staticBody;
                        bool activeB = bB.IsAwake() && typeB != b2BodyType.b2_staticBody;

                        // Is at least one body active (awake and dynamic or kinematic)?
                        if (activeA == false && activeB == false)
                        {
                            continue;
                        }

                        bool collideA = bA.IsBullet() || typeA != b2BodyType.b2_dynamicBody;
                        bool collideB = bB.IsBullet() || typeB != b2BodyType.b2_dynamicBody;

                        // Are these two non-bullet dynamic bodies?
                        if (collideA == false && collideB == false)
                        {
                            continue;
                        }

                        // Compute the TOI for this contact.
                        // Put the sweeps onto the same time interval.
                        float alpha0 = bA.Sweep.alpha0;

                        if (bA.Sweep.alpha0 < bB.Sweep.alpha0)
                        {
                            alpha0 = bB.Sweep.alpha0;
                            bA.Sweep.Advance(alpha0);
                        }
                        else if (bB.Sweep.alpha0 < bA.Sweep.alpha0)
                        {
                            alpha0 = bA.Sweep.alpha0;
                            bB.Sweep.Advance(alpha0);
                        }

                        int indexA = c.GetChildIndexA();
                        int indexB = c.GetChildIndexB();

                        // Compute the time of impact in interval [0, minTOI]
                        b2TOIInput input = new b2TOIInput();
                        input.proxyA.Set(fA.Shape, indexA);
                        input.proxyB.Set(fB.Shape, indexB);
                        input.sweepA = bA.Sweep;
                        input.sweepB = bB.Sweep;
                        input.tMax   = 1.0f;

                        b2TOIOutput output = b2TimeOfImpact(input);

                        // Beta is the fraction of the remaining portion of the .
                        float beta = output.t;
                        if (output.state == b2TOIOutputType.e_touching)
                        {
                            alpha = b2Math.b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
                        }
                        else
                        {
                            alpha = 1.0f;
                        }

                        c.m_toi         = alpha;
                        c.ContactFlags |= b2ContactFlags.e_toiFlag;
                    }

                    if (alpha < minAlpha)
                    {
                        // This is the minimum TOI found so far.
                        minContact = c;
                        minAlpha   = alpha;
                    }
                }

                if (minContact == null || 1.0f - 10.0f * b2Settings.b2_epsilon < minAlpha)
                {
                    // No more TOI events. Done!
                    m_stepComplete = true;
                    break;
                }
                {
                    // Advance the bodies to the TOI.
                    b2Fixture fA = minContact.GetFixtureA();
                    b2Fixture fB = minContact.GetFixtureB();
                    b2Body    bA = fA.Body;
                    b2Body    bB = fB.Body;

                    b2Sweep backup1 = bA.Sweep;
                    b2Sweep backup2 = bB.Sweep;

                    bA.Advance(minAlpha);
                    bB.Advance(minAlpha);

                    // The TOI contact likely has some new contact points.
                    minContact.Update(m_contactManager.ContactListener);
                    minContact.ContactFlags &= ~b2ContactFlags.e_toiFlag;
                    ++minContact.m_toiCount;

                    // Is the contact solid?
                    if (minContact.IsEnabled() == false || minContact.IsTouching() == false)
                    {
                        // Restore the sweeps.
                        minContact.SetEnabled(false);
                        bA.Sweep = backup1;
                        bB.Sweep = backup2;
                        bA.SynchronizeTransform();
                        bB.SynchronizeTransform();
                        continue;
                    }

                    bA.SetAwake(true);
                    bB.SetAwake(true);

                    // Build the island
                    island.Clear();
                    island.Add(bA);
                    island.Add(bB);
                    island.Add(minContact);

                    bA.BodyFlags           |= b2BodyFlags.e_islandFlag;
                    bB.BodyFlags           |= b2BodyFlags.e_islandFlag;
                    minContact.ContentType |= b2ContactFlags.e_islandFlag;

                    // Get contacts on bodyA and bodyB.
                    b2Body[] bodies = new b2Body[] { bA, bB };
                    for (int i = 0; i < 2; ++i)
                    {
                        b2Body body = bodies[i];
                        if (body.BodyType == b2BodyType.b2_dynamicBody)
                        {
                            for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
                            {
                                if (island.BodyCount == island.BodyCapacity)
                                {
                                    break;
                                }

                                if (island.ContactCount == island.ContactCapacity)
                                {
                                    break;
                                }

                                b2Contact contact = ce.contact;

                                // Has this contact already been added to the island?
                                if (contact.ContactType & b2ContactType.e_islandFlag)
                                {
                                    continue;
                                }

                                // Only add static, kinematic, or bullet bodies.
                                b2Body other = ce.other;
                                if (other.BodyType == b2BodyType.b2_dynamicBody &&
                                    body.IsBullet() == false && other.IsBullet() == false)
                                {
                                    continue;
                                }

                                // Skip sensors.
                                bool sensorA = contact.m_fixtureA.m_isSensor;
                                bool sensorB = contact.m_fixtureB.m_isSensor;
                                if (sensorA || sensorB)
                                {
                                    continue;
                                }

                                // Tentatively advance the body to the TOI.
                                b2Sweep backup = other.Sweep;
                                if (other.BodyFlags.HasFlag(b2BodyFlags.e_islandFlag))
                                {
                                    other.Advance(minAlpha);
                                }

                                // Update the contact points
                                contact.Update(m_contactManager.ContactListener);

                                // Was the contact disabled by the user?
                                if (contact.IsEnabled() == false)
                                {
                                    other.Sweep = backup;
                                    other.SynchronizeTransform();
                                    continue;
                                }

                                // Are there contact points?
                                if (contact.IsTouching() == false)
                                {
                                    other.Sweep = backup;
                                    other.SynchronizeTransform();
                                    continue;
                                }

                                // Add the contact to the island
                                contact.ContactFlags |= b2ContactFlags.e_islandFlag;
                                island.Add(contact);

                                // Has the other body already been added to the island?
                                if (other.BodyFlags.HasFlag(b2BodyFlags.e_islandFlag))
                                {
                                    continue;
                                }

                                // Add the other body to the island.
                                other.BodyFlags |= b2BodyFlags.e_islandFlag;

                                if (other.BodyType != b2BodyType.b2_staticBody)
                                {
                                    other.SetAwake(true);
                                }

                                island.Add(other);
                            }
                        }
                    }

                    b2TimeStep subStep;
                    subStep.dt                 = (1.0f - minAlpha) * step.dt;
                    subStep.inv_dt             = 1.0f / subStep.dt;
                    subStep.dtRatio            = 1.0f;
                    subStep.positionIterations = 20;
                    subStep.velocityIterations = step.velocityIterations;
                    subStep.warmStarting       = false;
                    island.SolveTOI(subStep, bA.m_islandIndex, bB.m_islandIndex);

                    // Reset island flags and synchronize broad-phase proxies.
                    for (int i = 0; i < island.m_bodyCount; ++i)
                    {
                        b2Body body = island.m_bodies[i];
                        body.BodyFlags &= ~b2BodyFlags.e_islandFlag;

                        if (body.BodyType != b2BodyType.b2_dynamicBody)
                        {
                            continue;
                        }

                        body.SynchronizeFixtures();

                        // Invalidate all contact TOIs on this displaced body.
                        for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
                        {
                            ce.Contact.ContactFlags &= ~(b2ContactFlags.e_toiFlag | b2ContactFlags.e_islandFlag);
                        }
                    }

                    // Commit fixture proxy movements to the broad-phase so that new contacts are created.
                    // Also, some contacts can be destroyed.
                    m_contactManager.FindNewContacts();

                    if (m_subStepping)
                    {
                        m_stepComplete = false;
                        break;
                    }
                }
            }
        }
예제 #29
0
        public void AddPair(object proxyUserDataA, object proxyUserDataB)
        {
            b2FixtureProxy proxyA = (b2FixtureProxy)proxyUserDataA;
            b2FixtureProxy proxyB = (b2FixtureProxy)proxyUserDataB;

            b2Fixture fixtureA = proxyA.fixture;
            b2Fixture fixtureB = proxyB.fixture;

            int indexA = proxyA.childIndex;
            int indexB = proxyB.childIndex;

            b2Body bodyA = fixtureA.GetBody();
            b2Body bodyB = fixtureB.GetBody();

            // Are the fixtures on the same body?
            if (bodyA == bodyB)
            {
                return;
            }

            // TODO_ERIN use a hash table to remove a potential bottleneck when both
            // bodies have a lot of contacts.
            // Does a contact already exist?
            b2ContactEdge edge = bodyB.GetContactList();

            while (edge)
            {
                if (edge.other == bodyA)
                {
                    b2Fixture fA = edge.contact.GetFixtureA();
                    b2Fixture fB = edge.contact.GetFixtureB();
                    int       iA = edge.contact.GetChildIndexA();
                    int       iB = edge.contact.GetChildIndexB();

                    if (fA == fixtureA && fB == fixtureB && iA == indexA && iB == indexB)
                    {
                        // A contact already exists.
                        return;
                    }

                    if (fA == fixtureB && fB == fixtureA && iA == indexB && iB == indexA)
                    {
                        // A contact already exists.
                        return;
                    }
                }

                edge = edge.next;
            }

            // Does a joint override collision? Is at least one body dynamic?
            if (bodyB.ShouldCollide(bodyA) == false)
            {
                return;
            }

            // Check user filtering.
            if (m_contactFilter && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

            // Call the factory.
            b2Contact c = b2Contact.Create(fixtureA, indexA, fixtureB, indexB, m_allocator);

            if (c == null)
            {
                return;
            }

            // Contact creation may swap fixtures.
            fixtureA = c.GetFixtureA();
            fixtureB = c.GetFixtureB();
            indexA   = c.GetChildIndexA();
            indexB   = c.GetChildIndexB();
            bodyA    = fixtureA.GetBody();
            bodyB    = fixtureB.GetBody();

            // Insert into the world.
            c.m_prev = null;
            c.m_next = m_contactList;
            if (m_contactList != null)
            {
                m_contactList.m_prev = c;
            }
            m_contactList = c;

            // Connect to island graph.

            // Connect to body A
            c.m_nodeA.contact = c;
            c.m_nodeA.other   = bodyB;

            c.m_nodeA.prev = null;
            c.m_nodeA.next = bodyA.m_contactList;
            if (bodyA.m_contactList != null)
            {
                bodyA.m_contactList.prev = &c.m_nodeA;
            }
            bodyA.m_contactList = &c.m_nodeA;

            // Connect to body B
            c.m_nodeB.contact = c;
            c.m_nodeB.other   = bodyA;

            c.m_nodeB.prev = null;
            c.m_nodeB.next = bodyB.m_contactList;
            if (bodyB.m_contactList != null)
            {
                bodyB.m_contactList.prev = &c.m_nodeB;
            }
            bodyB.m_contactList = &c.m_nodeB;

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

            ++m_contactCount;
        }
예제 #30
0
        // This is the top level collision call for the time step. Here
        // all the narrow phase collision is processed for the world
        // contact list.
        public void Collide()
        {
            // Update awake contacts.
            b2Contact c = m_contactList;

            while (c)
            {
                b2Fixture fixtureA = c.GetFixtureA();
                b2Fixture fixtureB = c.GetFixtureB();
                int       indexA   = c.GetChildIndexA();
                int       indexB   = c.GetChildIndexB();
                b2Body    bodyA    = fixtureA.GetBody();
                b2Body    bodyB    = fixtureB.GetBody();

                // Is this contact flagged for filtering?
                if (c.m_flags & b2Contact.e_filterFlag)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        b2Contact cNuke = c;
                        c = cNuke.GetNext();
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (m_contactFilter && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        b2Contact cNuke = c;
                        c = cNuke.GetNext();
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag.
                    c.m_flags &= ~b2Contact.e_filterFlag;
                }

                bool activeA = bodyA.IsAwake() && bodyA.m_type != b2BodyType.b2_staticBody;
                bool activeB = bodyB.IsAwake() && bodyB.m_type != b2BodyType.b2_staticBody;

                // At least one body must be awake and it must be dynamic or kinematic.
                if (activeA == false && activeB == false)
                {
                    c = c.GetNext();
                    continue;
                }

                int  proxyIdA = fixtureA.m_proxies[indexA].proxyId;
                int  proxyIdB = fixtureB.m_proxies[indexB].proxyId;
                bool overlap  = m_broadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    b2Contact cNuke = c;
                    c = cNuke.GetNext();
                    Destroy(cNuke);
                    continue;
                }

                // The contact persists.
                c.Update(m_contactListener);
                c = c.GetNext();
            }
        }
예제 #31
0
        // REVISADO =====================================================================
        b2Fixture j2b2Fixture(b2Body body, JObject fixtureValue)
        {
            if (null == fixtureValue)
                return null;

            b2FixtureDef fixtureDef = new b2FixtureDef();

            //Fixture fixtureDef = new Fixture();
            fixtureDef.restitution = jsonToFloat("restitution", fixtureValue);
            fixtureDef.friction = jsonToFloat("friction", fixtureValue);
            fixtureDef.density = jsonToFloat("density", fixtureValue);
            fixtureDef.isSensor = fixtureValue["sensor"] == null ? false : (bool)fixtureValue["sensor"];

            fixtureDef.filter.categoryBits = (fixtureValue["filter-categoryBits"] == null) ? (ushort)0x0001 : (ushort)fixtureValue["filter-categoryBits"];

            fixtureDef.filter.maskBits = fixtureValue["filter-maskBits"] == null ? (ushort)0xffff : (ushort)fixtureValue["filter-maskBits"];

            fixtureDef.filter.groupIndex = fixtureValue["filter-groupIndex"] == null ? (short)0 : (short)fixtureValue["filter-groupIndex"];

            b2Fixture fixture = null;

            if (null != fixtureValue["circle"])
            {
                JObject circleValue = (JObject)fixtureValue["circle"];

                b2CircleShape circleShape = new b2CircleShape();

                circleShape.Radius = jsonToFloat("radius", circleValue);
                circleShape.Position = jsonToVec("center", circleValue);

                fixtureDef.shape = circleShape;
                fixture = body.CreateFixture(fixtureDef);
            }
            else if (null != fixtureValue["edge"])
            {

                JObject edgeValue = (JObject)fixtureValue["edge"];
                b2EdgeShape edgeShape = new b2EdgeShape();

                edgeShape.Vertex1 = jsonToVec("vertex1", edgeValue);
                edgeShape.Vertex2 = jsonToVec("vertex2", edgeValue);

                edgeShape.HasVertex0 = edgeValue["hasVertex0"] == null ? false : (bool)edgeValue["hasVertex0"];
                edgeShape.HasVertex3 = edgeValue["hasVertex3"] == null ? false : (bool)edgeValue["hasVertex3"];

                if (edgeShape.HasVertex0)
                    edgeShape.Vertex0 = jsonToVec("vertex0", edgeValue);
                if (edgeShape.HasVertex3)
                    edgeShape.Vertex3 = jsonToVec("vertex3", edgeValue);
                fixtureDef.shape = edgeShape;

                fixture = body.CreateFixture(fixtureDef);
            }
            else if (null != fixtureValue["loop"])
            {// support old
                // format (r197)

                JObject chainValue = (JObject)fixtureValue["loop"];
                b2ChainShape chainShape = new b2ChainShape();

                int numVertices = ((JArray)chainValue["x"]).Count;

                b2Vec2[] vertices = new b2Vec2[numVertices];
                for (int i = 0; i < numVertices; i++)
                    vertices[i] = jsonToVec("vertices", chainValue, i);

                chainShape.CreateLoop(vertices, numVertices);

                fixtureDef.shape = chainShape;
                fixture = body.CreateFixture(fixtureDef);

            }
            else if (null != fixtureValue["chain"])
            {

                // FPE. See http://www.box2d.org/forum/viewtopic.php?f=4&t=7973&p=35363

                JObject chainValue = (JObject)fixtureValue["chain"];
                b2ChainShape chainShape = new b2ChainShape();
                int numVertices = ((JArray)chainValue["vertices"]["x"]).Count;
                var vertices = new b2Vec2[numVertices];

                for (int i = 0; i < numVertices; i++)
                    vertices[i] = jsonToVec("vertices", chainValue, i);

                chainShape.CreateChain(vertices, numVertices);
                chainShape.HasPrevVertex = chainValue["hasPrevVertex"] == null ? false : (bool)chainValue["hasPrevVertex"];
                chainShape.HasNextVertex = chainValue["hasNextVertex"] == null ? false : (bool)chainValue["hasNextVertex"];

                if (chainShape.HasPrevVertex)
                    chainShape.PrevVertex = (jsonToVec("prevVertex", chainValue));
                if (chainShape.HasNextVertex)
                    chainShape.NextVertex = (jsonToVec("nextVertex", chainValue));

                fixtureDef.shape = chainShape;
                fixture = body.CreateFixture(fixtureDef);

            }
            else if (null != fixtureValue["polygon"])
            {

                JObject polygonValue = (JObject)fixtureValue["polygon"];
                b2Vec2[] vertices = new b2Vec2[b2Settings.b2_maxPolygonVertices];

                int numVertices = ((JArray)polygonValue["vertices"]["x"]).Count;
                if (numVertices > b2Settings.b2_maxPolygonVertices)
                {
                    Console.WriteLine("Ignoring polygon fixture with too many vertices.");
                }
                else if (numVertices < 2)
                {
                    Console.WriteLine("Ignoring polygon fixture less than two vertices.");
                }
                else if (numVertices == 2)
                {
                    Console.WriteLine("Creating edge shape instead of polygon with two vertices.");

                    b2EdgeShape edgeShape = new b2EdgeShape();
                    edgeShape.Vertex1 = jsonToVec("vertices", polygonValue, 0);
                    edgeShape.Vertex2 = jsonToVec("vertices", polygonValue, 1);
                    fixtureDef.shape = edgeShape;
                    fixture = body.CreateFixture(fixtureDef);

                }
                else
                {

                    b2PolygonShape polygonShape = new b2PolygonShape();
                    for (int i = 0; i < numVertices; i++)
                        vertices[i] = jsonToVec("vertices", polygonValue, i);
                    polygonShape.Set(vertices, numVertices);
                    fixtureDef.shape = polygonShape;
                    fixture = body.CreateFixture(fixtureDef);
                }
            }

            String fixtureName = fixtureValue["name"] == null ? "" : fixtureValue["name"].ToString();
            if (fixtureName != "")
            {
                SetFixtureName(fixture, fixtureName);
            }

            return fixture;
        }
예제 #32
0
        public JObject B2n(b2Body body)
        {
            JObject bodyValue = new JObject();

            string bodyName = GetBodyName(body);
            if (null != bodyName)
                bodyValue["name"] = bodyName;

            switch (body.BodyType)
            {
                case b2BodyType.b2_staticBody:
                    bodyValue["type"] = 0;
                    break;
                case b2BodyType.b2_kinematicBody:
                    bodyValue["type"] = 1;
                    break;
                case b2BodyType.b2_dynamicBody:
                    bodyValue["type"] = 2;
                    break;
            }

            VecToJson("position", body.Position, bodyValue);
            FloatToJson("angle", body.Angle, bodyValue);

            VecToJson("linearVelocity", body.LinearVelocity, bodyValue);
            FloatToJson("angularVelocity", body.AngularVelocity, bodyValue);

            if (body.LinearDamping != 0)
                FloatToJson("linearDamping", body.LinearDamping, bodyValue);
            if (body.AngularDamping != 0)
                FloatToJson("angularDamping", body.AngularDamping, bodyValue);
            if (body.GravityScale != 1)
                FloatToJson("gravityScale", body.GravityScale, bodyValue);

            if (body.IsBullet())
                bodyValue["bullet"] = true;
            if (!body.IsSleepingAllowed())
                bodyValue["allowSleep"] = false;
            if (body.IsAwake())
                bodyValue["awake"] = true;
            if (!body.IsActive())
                bodyValue["active"] = false;
            if (body.IsFixedRotation())
                bodyValue["fixedRotation"] = true;

            b2MassData massData = new b2MassData();
            massData = body.GetMassData();

            if (massData.mass != 0)
                FloatToJson("massData-mass", massData.mass, bodyValue);
            if (massData.center.x != 0 || massData.center.y != 0)
                VecToJson("massData-center", body.LocalCenter, bodyValue);
            if (massData.I != 0)
            {
                FloatToJson("massData-I", massData.I, bodyValue);
            }

            //int i = 0;
            JArray arr = new JArray();
            b2Body tmp = body;
            while (tmp != null)
            {
                bodyValue.Add("fixture", B2n(tmp));
                tmp = body.Next;
            }

            bodyValue["fixture"] = arr;

            JArray customPropertyValue = WriteCustomPropertiesToJson(body);
            if (customPropertyValue.Count > 0)
                bodyValue["customProperties"] = customPropertyValue;

            return bodyValue;
        }
예제 #33
0
 public void SetCustomVector(b2Body item, String propertyName, b2Vec2 val)
 {
     m_bodiesWithCustomProperties.Add(item);
     GetCustomPropertiesForItem(item, true).m_customPropertyMap_vec2.Add(propertyName, val);
 }
예제 #34
0
 public void SetCustomString(b2Body item, String propertyName, String val)
 {
     m_bodiesWithCustomProperties.Add(item);
     GetCustomPropertiesForItem(item, true).m_customPropertyMap_string.Add(propertyName, val);
 }
예제 #35
0
 public void SetCustomFloat(b2Body item, String propertyName, float val)
 {
     m_bodiesWithCustomProperties.Add(item);
     GetCustomPropertiesForItem(item, true).m_customPropertyMap_float.Add(propertyName, (float)val);
 }
예제 #36
0
        public b2Joint CreateJoint(b2JointDef def)
        {
            if (IsLocked())
            {
                return(null);
            }

            b2Joint j = b2Joint.Create(def);

            // Connect to the world list.
            j.Prev = null;
            j.Next = m_jointList;
            if (m_jointList)
            {
                m_jointList.Prev = j;
            }
            m_jointList = j;
            ++m_jointCount;

            // Connect to the bodies' doubly linked lists.
            j.m_edgeA.joint = j;
            j.m_edgeA.other = j.m_bodyB;
            j.m_edgeA.prev  = null;
            j.m_edgeA.next  = j.m_bodyA.JointList;
            if (j.m_bodyA.JointList)
            {
                j.m_bodyA.JointList.prev = &j.m_edgeA;
            }
            j.m_bodyA.JointList = &j.m_edgeA;

            j.m_edgeB.joint = j;
            j.m_edgeB.other = j.m_bodyA;
            j.m_edgeB.prev  = null;
            j.m_edgeB.next  = j.m_bodyB.JointList;
            if (j.m_bodyB.JointList)
            {
                j.m_bodyB.JointList.prev = &j.m_edgeB;
            }
            j.m_bodyB.JointList = &j.m_edgeB;

            b2Body bodyA = def.bodyA;
            b2Body bodyB = def.bodyB;

            // If the joint prevents collisions, then flag any contacts for filtering.
            if (def.collideConnected == false)
            {
                b2ContactEdge edge = bodyB.ContactList;
                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);
        }
예제 #37
0
        // This is a callback from the broadphase when two AABB proxies begin
        // to overlap. We create a b2Contact to manage the narrow phase.
        public void AddPair(object proxyUserDataA, object proxyUserDataB)
        {
            b2Fixture fixtureA = proxyUserDataA as b2Fixture;
            b2Fixture fixtureB = proxyUserDataB as b2Fixture;

            b2Body bodyA = fixtureA.GetBody();
            b2Body bodyB = fixtureB.GetBody();

            // Are the fixtures on the same body?
            if (bodyA == bodyB)
            {
                return;
            }

            // Does a contact already exist?
            b2ContactEdge edge = bodyB.GetContactList();

            while (edge != null)
            {
                if (edge.other == bodyA)
                {
                    b2Fixture fA = edge.contact.GetFixtureA();
                    b2Fixture fB = edge.contact.GetFixtureB();
                    if (fA == fixtureA && fB == fixtureB)
                    {
                        return;
                    }
                    if (fA == fixtureB && fB == fixtureA)
                    {
                        return;
                    }
                }
                edge = edge.next;
            }

            //Does a joint override collision? Is at least one body dynamic?
            if (bodyB.ShouldCollide(bodyA) == false)
            {
                return;
            }

            // Check user filtering
            if (m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

            // Call the factory.
            b2Contact c = m_contactFactory.Create(fixtureA, fixtureB);

            // Contact creation may swap shapes.
            fixtureA = c.GetFixtureA();
            fixtureB = c.GetFixtureB();
            bodyA    = fixtureA.m_body;
            bodyB    = fixtureB.m_body;

            // Insert into the world.
            c.m_prev = null;
            c.m_next = m_world.m_contactList;
            if (m_world.m_contactList != null)
            {
                m_world.m_contactList.m_prev = c;
            }
            m_world.m_contactList = c;


            // Connect to island graph.

            // Connect to body A
            c.m_nodeA.contact = c;
            c.m_nodeA.other   = bodyB;

            c.m_nodeA.prev = null;
            c.m_nodeA.next = bodyA.m_contactList;
            if (bodyA.m_contactList != null)
            {
                bodyA.m_contactList.prev = c.m_nodeA;
            }
            bodyA.m_contactList = c.m_nodeA;

            // Connect to body 2
            c.m_nodeB.contact = c;
            c.m_nodeB.other   = bodyA;

            c.m_nodeB.prev = null;
            c.m_nodeB.next = bodyB.m_contactList;
            if (bodyB.m_contactList != null)
            {
                bodyB.m_contactList.prev = c.m_nodeB;
            }
            bodyB.m_contactList = c.m_nodeB;

            ++m_world.m_contactCount;
            return;
        }
예제 #38
0
        public void Destroy(b2Contact c)
        {
            b2Fixture fixtureA = c.GetFixtureA();
            b2Fixture fixtureB = c.GetFixtureB();
            b2Body    bodyA    = fixtureA.GetBody();
            b2Body    bodyB    = fixtureB.GetBody();

            if (m_contactListener && c.IsTouching())
            {
                m_contactListener.EndContact(c);
            }

            // Remove from the world.
            if (c.m_prev)
            {
                c.m_prev.m_next = c.m_next;
            }

            if (c.m_next)
            {
                c.m_next.m_prev = c.m_prev;
            }

            if (c == m_contactList)
            {
                m_contactList = c.m_next;
            }

            // Remove from body 1
            if (c.m_nodeA.prev)
            {
                c.m_nodeA.prev.next = c.m_nodeA.next;
            }

            if (c.m_nodeA.next)
            {
                c.m_nodeA.next.prev = c.m_nodeA.prev;
            }

            if (c.m_nodeA == bodyA.m_contactList)
            {
                bodyA.m_contactList = c.m_nodeA.next;
            }

            // Remove from body 2
            if (c.m_nodeB.prev)
            {
                c.m_nodeB.prev.next = c.m_nodeB.next;
            }

            if (c.m_nodeB.next)
            {
                c.m_nodeB.next.prev = c.m_nodeB.prev;
            }

            if (c.m_nodeB == bodyB.m_contactList)
            {
                bodyB.m_contactList = c.m_nodeB.next;
            }

            // Call the factory.
            b2Contact.Destroy(c);
            --m_contactCount;
        }
예제 #39
0
 public void clear()
 {
     m_mouseJoint = null;
     m_mouseJointGroundBody = null;
 }
예제 #40
0
 public void AddBody(b2Body body)
 {
     //b2Settings.b2Assert(m_bodyCount < m_bodyCapacity);
     body.m_islandIndex      = m_bodyCount;
     m_bodies[m_bodyCount++] = body;
 }
            public Car(
                b2World b2world,

                double width,
                double length,
                double[] position,
                double angle,
                double power,
                double max_steer_angle,
                double max_speed,
                Wheel[] wheels
                )
            {
                //        /*
                //        pars is an object with possible attributes:

                //        width - width of the car in meters
                //        length - length of the car in meters
                //        position - starting position of the car, array [x, y] in meters
                //        angle - starting angle of the car, degrees
                //        max_steer_angle - maximum angle the wheels turn when steering, degrees
                //        max_speed       - maximum speed of the car, km/h
                //        power - engine force, in newtons, that is applied to EACH powered wheel
                //        wheels - wheel definitions: [{x, y, rotatable, powered}}, ...] where
                //                 x is wheel position in meters relative to car body center
                //                 y is wheel position in meters relative to car body center
                //                 revolving - boolean, does this turn rotate when steering?
                //                 powered - is force applied to this wheel when accelerating/braking?
                //        */



                //        this.max_steer_angle=pars.max_steer_angle;
                //        this.max_speed=pars.max_speed;
                //        this.power=pars.power;
                var wheel_angle = 0.0;//keep track of current wheel angle relative to car.
                //                           //when steering left/right, angle will be decreased/increased gradually over 200ms to prevent jerkyness.

                //initialize body
                var def = new b2BodyDef();
                def.type = b2Body.b2_dynamicBody;
                def.position = new b2Vec2(position[0], position[1]);
                def.angle = angle.DegreesToRadians();
                def.linearDamping = 0.15;  //gradually reduces velocity, makes the car reduce speed slowly if neither accelerator nor brake is pressed
                def.bullet = true; //dedicates more time to collision detection - car travelling at high speeds at low framerates otherwise might teleport through obstacles.
                def.angularDamping = 0.3;

                this.body = b2world.CreateBody(def);

                //initialize shape
                var fixdef = new b2FixtureDef();
                fixdef.density = 1.0;
                fixdef.friction = 0.3; //friction when rubbing agaisnt other shapes
                fixdef.restitution = 0.4;  //amount of force feedback when hitting something. >0 makes the car bounce off, it's fun!

                var fixdef_shape = new b2PolygonShape();

                fixdef.shape = fixdef_shape;
                fixdef_shape.SetAsBox(width / 2, length / 2);
                body.CreateFixture(fixdef);

                //initialize wheels
                foreach (var item in wheels)
                {
                    item.Initialize(this);
                }

                //return array of wheels that turn when steering
                IEnumerable<Wheel> getRevolvingWheels = from w in wheels where w.revolving select w;
                //        //return array of powered wheels
                IEnumerable<Wheel> getPoweredWheels = from w in wheels where w.powered select w;

                #region setSpeed
                Action<double> setSpeed = (speed) =>
                {
                    /*
                    speed - speed in kilometers per hour
                    */
                    var velocity0 = this.body.GetLinearVelocity();

                    //Console.WriteLine("car setSpeed velocity0 " + new { velocity0.x, velocity0.y });

                    var velocity2 = vectors.unit(new[] { velocity0.x, velocity0.y });

                    //Console.WriteLine("car setSpeed velocity2 " + new { x = velocity2[0], y = velocity2[1] });
                    var velocity = new b2Vec2(
                        velocity2[0] * ((speed * 1000.0) / 3600.0),
                        velocity2[1] * ((speed * 1000.0) / 3600.0)
                    );

                    //Console.WriteLine("car setSpeed SetLinearVelocity " + new { velocity.x, velocity.y });
                    this.body.SetLinearVelocity(velocity);

                };
                #endregion


                #region getSpeedKMH
                Func<double> getSpeedKMH = delegate
                {
                    var velocity = this.body.GetLinearVelocity();
                    var len = vectors.len(new double[] { velocity.x, velocity.y });
                    return (len / 1000.0) * 3600.0;
                };
                #endregion

                #region getLocalVelocity
                Func<double[]> getLocalVelocity = delegate
                {
                    /*
                    returns car's velocity vector relative to the car
                    */
                    var retv = this.body.GetLocalVector(this.body.GetLinearVelocityFromLocalPoint(new b2Vec2(0, 0)));
                    return new double[] { retv.x, retv.y };
                };
                #endregion



                #region update
                this.update = (msDuration) =>
                {


                    #region 1. KILL SIDEWAYS VELOCITY

                    //kill sideways velocity for all wheels
                    for (var i = 0; i < wheels.Length; i++)
                    {
                        wheels[i].killSidewaysVelocity();
                    }
                    #endregion



                    #region 2. SET WHEEL ANGLE

                    //calculate the change in wheel's angle for this update, assuming the wheel will reach is maximum angle from zero in 200 ms
                    var incr = (max_steer_angle / 200.0) * msDuration;

                    if (steer == STEER_RIGHT)
                    {
                        wheel_angle = Math.Min(Math.Max(wheel_angle, 0) + incr, max_steer_angle); //increment angle without going over max steer
                    }
                    else if (steer == STEER_LEFT)
                    {
                        wheel_angle = Math.Max(Math.Min(wheel_angle, 0) - incr, -max_steer_angle); //decrement angle without going over max steer
                    }
                    else
                    {
                        wheel_angle = 0;
                    }

                    //update revolving wheels
                    getRevolvingWheels.WithEach(
                        w => w.setAngle(wheel_angle)
                    );

                    #endregion


                    #region 3. APPLY FORCE TO WHEELS
                    var base_vect = new double[2]; //vector pointing in the direction force will be applied to a wheel ; relative to the wheel.

                    //if accelerator is pressed down and speed limit has not been reached, go forwards
                    var lessthanlimit = (getSpeedKMH() < max_speed);
                    var flag1 = (accelerate == ACC_ACCELERATE) && lessthanlimit;
                    if (flag1)
                    {
                        base_vect = new double[] { 0, -1 };
                    }
                    else if (accelerate == ACC_BRAKE)
                    {
                        //braking, but still moving forwards - increased force
                        if (getLocalVelocity()[1] < 0)
                        {
                            base_vect = new double[] { 0, 1.3 };
                        }
                        //going in reverse - less force
                        else
                        {
                            base_vect = new double[] { 0, 0.7 };
                        }
                    }
                    else
                    {
                        base_vect[0] = 0;
                        base_vect[1] = 0;
                    }

                    //multiply by engine power, which gives us a force vector relative to the wheel
                    var fvect = new double[] { 
                        power * base_vect[0], 
                        power * base_vect[1] 
                    };

                    //apply force to each wheel



                    getPoweredWheels.WithEachIndex(
                        (w, i) =>
                        {
                            var wp = w.body.GetWorldCenter();
                            var wf = w.body.GetWorldVector(new b2Vec2(fvect[0], fvect[1]));

                            //Console.WriteLine("getPoweredWheels ApplyForce #" + i);
                            w.body.ApplyForce(wf, wp);
                        }
                    );




                    //if going very slow, stop - to prevent endless sliding
                    var veryslow = (getSpeedKMH() < 4);
                    var flag2 = veryslow && (accelerate == ACC_NONE);
                    if (flag2)
                    {
                        //Console.WriteLine("setSpeed 0");
                        setSpeed(0);
                    }
                    #endregion


                };
                #endregion

            }
예제 #42
0
 public override void EndContact(Box2D.Dynamics.Contacts.b2Contact contact)
 {
     if (contact.FixtureA.UserData != null && contact.FixtureB.UserData != null) {
         switch ((WorldFixtureData)contact.FixtureA.UserData) {
         case WorldFixtureData.playergroundsensor:
             if ((WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.platform) {
                 playerGroundBody = null;
                 playerGround = WorldFixtureData.air;
             } else if ((WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.jumppad) {
                 playerGroundJumpPad = null;
                 playerGround = WorldFixtureData.air;
             }
             else {
                 playerGround = WorldFixtureData.air;
             }
             break;
         case WorldFixtureData.playerleftsensor:
             WallContact = Direction.None;
             break;
         case WorldFixtureData.playerrightsensor:
             WallContact = Direction.None;
             break;
         default:
             switch ((WorldFixtureData)contact.FixtureB.UserData) {
             case WorldFixtureData.playergroundsensor:
                 if ((WorldFixtureData)contact.FixtureA.UserData == WorldFixtureData.platform) {
                     playerGroundBody = null;
                     playerGround = WorldFixtureData.air;
                 } else if ((WorldFixtureData)contact.FixtureA.UserData == WorldFixtureData.jumppad) {
                     playerGroundJumpPad = null;
                     playerGround = WorldFixtureData.air;
                 } else {
                     playerGround = WorldFixtureData.air;
                 }
                 break;
             case WorldFixtureData.playerleftsensor:
                 WallContact = Direction.None;
                 break;
             case WorldFixtureData.playerrightsensor:
                 WallContact = Direction.None;
                 break;
             }
             break;
         }
         if ((WorldFixtureData)contact.FixtureA.UserData == WorldFixtureData.playergroundsensor && (WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.platform ||
             (WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.playergroundsensor && (WorldFixtureData)contact.FixtureA.UserData == WorldFixtureData.platform) {
                 } else if ((WorldFixtureData)contact.FixtureA.UserData == WorldFixtureData.playergroundsensor || (WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.playergroundsensor) {
             }
     }
 }
예제 #43
0
 public void Add(b2Body body)
 {
     Debug.Assert(m_bodyCount < m_bodyCapacity);
     body.IslandIndex = m_bodyCount;
     m_bodies[m_bodyCount] = body;
     ++m_bodyCount;
 }
예제 #44
0
        public override void BeginContact(Box2D.Dynamics.Contacts.b2Contact contact)
        {
            base.BeginContact (contact);

            if (contact.FixtureA.UserData != null && contact.FixtureB.UserData != null) {
                switch ((WorldFixtureData)contact.FixtureA.UserData) {
                case WorldFixtureData.playergroundsensor:
                    switch ((WorldFixtureData)contact.FixtureB.UserData) {
                    case WorldFixtureData.ground:
                        playerGround = WorldFixtureData.ground;
                        break;
                    case WorldFixtureData.platform:
                        playerGround = WorldFixtureData.platform;
                        playerGroundBody = contact.FixtureB.Body;
                        break;
                    case WorldFixtureData.jumppad:
                        playerGround = WorldFixtureData.jumppad;
                        playerGroundJumpPad = gameContainer.jumpPadContainer.First (search => search.JumpPadBody.Position == contact.FixtureB.Body.Position);
                        break;
                    default:
                        playerGround = WorldFixtureData.air;
                        break;
                    }
                    break;
                case WorldFixtureData.playerleftsensor:
                    if ((WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.ground) {
                        WallContact = Direction.Left;
                    } else {
                        WallContact = Direction.None;
                    }
                    break;
                case WorldFixtureData.playerrightsensor:
                    if ((WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.ground) {
                        WallContact = Direction.Right;
                    } else {
                        WallContact = Direction.None;
                    }
                    break;
                default:
                    switch ((WorldFixtureData)contact.FixtureB.UserData) {
                    case WorldFixtureData.playergroundsensor:
                        switch ((WorldFixtureData)contact.FixtureA.UserData) {
                        case WorldFixtureData.ground:
                            playerGround = WorldFixtureData.ground;
                            break;
                        case WorldFixtureData.platform:
                            playerGround = WorldFixtureData.platform;
                            playerGroundBody = contact.FixtureA.Body;
                            break;
                        case WorldFixtureData.jumppad:
                            playerGround = WorldFixtureData.jumppad;
                            playerGroundJumpPad = gameContainer.jumpPadContainer.First (search => search.JumpPadBody.Position == contact.FixtureB.Body.Position);
                            break;
                        default:
                            playerGround = WorldFixtureData.air;
                            break;
                        }
                        break;
                    case WorldFixtureData.playerleftsensor:
                        if ((WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.ground) {
                            WallContact = Direction.Left;
                        } else {
                            WallContact = Direction.None;
                        }
                        break;
                    case WorldFixtureData.playerrightsensor:
                        if ((WorldFixtureData)contact.FixtureB.UserData == WorldFixtureData.ground) {
                            WallContact = Direction.Right;
                        } else {
                            WallContact = Direction.None;
                        }
                        break;
                    }
                    break;
                }
            }
        }
예제 #45
0
        public void Solve(b2TimeStep step, b2Vec2 gravity, bool allowSleep)
#endif
        {
#if PROFILING
            b2Timer timer = new b2Timer();
#endif
            float h = step.dt;

            // Integrate velocities and apply damping. Initialize the body state.
            for (int i = 0; i < m_bodyCount; ++i)
            {
                b2Body b = m_bodies[i];

                b2Vec2 c = b.Sweep.c;
                float  a = b.Sweep.a;
                b2Vec2 v = b.LinearVelocity;
                float  w = b.AngularVelocity;

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

                if (b.BodyType == b2BodyType.b2_dynamicBody)
                {
                    // Integrate velocities.
                    v += h * (b.GravityScale * gravity + b.InvertedMass * b.Force);
                    w += h * b.InvertedI * 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
                    v *= b2Math.b2Clamp(1.0f - h * b.LinearDamping, 0.0f, 1.0f);
                    w *= b2Math.b2Clamp(1.0f - h * b.AngularDamping, 0.0f, 1.0f);
                }

                m_positions[i].c  = c;
                m_positions[i].a  = a;
                m_velocities[i].v = v;
                m_velocities[i].w = w;
            }

#if PROFILING
            timer.Reset();
#endif
            // Solver data
            b2SolverData solverData = new b2SolverData();
            solverData.step       = step;
            solverData.positions  = m_positions;
            solverData.velocities = m_velocities;

            // Initialize velocity constraints.
            b2ContactSolverDef contactSolverDef;
            contactSolverDef.step       = step;
            contactSolverDef.contacts   = m_contacts;
            contactSolverDef.count      = m_contactCount;
            contactSolverDef.positions  = m_positions;
            contactSolverDef.velocities = m_velocities;

            b2ContactSolver contactSolver = new b2ContactSolver(contactSolverDef);
            contactSolver.InitializeVelocityConstraints();

            if (step.warmStarting)
            {
                contactSolver.WarmStart();
            }

            for (int i = 0; i < m_jointCount; ++i)
            {
                m_joints[i].InitVelocityConstraints(solverData);
            }
#if PROFILING
            profile.solveInit = timer.GetMilliseconds();
#endif
            // Solve velocity constraints
#if PROFILING
            timer.Reset();
#endif
            for (int i = 0; i < step.velocityIterations; ++i)
            {
                for (int j = 0; j < m_jointCount; ++j)
                {
                    m_joints[j].SolveVelocityConstraints(solverData);
                }

                contactSolver.SolveVelocityConstraints();
            }

            // Store impulses for warm starting
            contactSolver.StoreImpulses();
#if PROFILING
            profile.solveVelocity = timer.GetMilliseconds();
#endif
            // Integrate positions
            for (int i = 0; i < m_bodyCount; ++i)
            {
                b2Vec2 c = m_positions[i].c;
                float  a = m_positions[i].a;
                b2Vec2 v = m_velocities[i].v;
                float  w = m_velocities[i].w;

                // Check for large velocities
                b2Vec2 translation = h * v;
                if (translation.LengthSquared /* b2Math.b2Dot(translation, translation)*/ > b2Settings.b2_maxTranslationSquared)
                {
                    float ratio = b2Settings.b2_maxTranslation / translation.Length;
                    v *= ratio;
                }

                float rotation = h * w;
                if (rotation * rotation > b2Settings.b2_maxRotationSquared)
                {
                    float ratio = b2Settings.b2_maxRotation / Math.Abs(rotation);
                    w *= ratio;
                }

                // Integrate
                c += h * v;
                a += h * w;

                m_positions[i].c  = c;
                m_positions[i].a  = a;
                m_velocities[i].v = v;
                m_velocities[i].w = w;
            }

            // Solve position constraints
#if PROFILING
            timer.Reset();
#endif
            bool positionSolved = false;
            for (int i = 0; i < step.positionIterations; ++i)
            {
                bool contactsOkay = contactSolver.SolvePositionConstraints();

                bool jointsOkay = true;
                for (int i2 = 0; i2 < m_jointCount; ++i2)
                {
                    bool jointOkay = m_joints[i2].SolvePositionConstraints(solverData);
                    jointsOkay = jointsOkay && jointOkay;
                }

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

            // Copy state buffers back to the bodies
            for (int i = 0; i < m_bodyCount; ++i)
            {
                b2Body body = m_bodies[i];
                body.Sweep.c         = m_positions[i].c;
                body.Sweep.a         = m_positions[i].a;
                body.LinearVelocity  = m_velocities[i].v;
                body.AngularVelocity = m_velocities[i].w;
                body.SynchronizeTransform();
            }
#if PROFILING
            profile.solvePosition = timer.GetMilliseconds();
#endif
            Report(contactSolver.m_velocityConstraints);

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

                float linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance;
                float angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance;

                for (int i = 0; i < m_bodyCount; ++i)
                {
                    b2Body b = m_bodies[i];
                    if (b.BodyType == b2BodyType.b2_staticBody)
                    {
                        continue;
                    }

                    if (!(b.BodyFlags.HasFlag(b2BodyFlags.e_autoSleepFlag)) ||
                        b.AngularVelocity * b.AngularVelocity > angTolSqr ||
                        b2Math.b2Dot(b.LinearVelocity, b.LinearVelocity) > linTolSqr)
                    {
                        b.SleepTime  = 0.0f;
                        minSleepTime = 0.0f;
                    }
                    else
                    {
                        b.SleepTime += h;
                        minSleepTime = Math.Min(minSleepTime, b.SleepTime);
                    }
                }

                if (minSleepTime >= b2Settings.b2_timeToSleep && positionSolved)
                {
                    for (int i = 0; i < m_bodyCount; ++i)
                    {
                        b2Body b = m_bodies[i];
                        b.SetAwake(false);
                    }
                }
            }
        }
예제 #46
0
        public b2Body(b2BodyDef bd, b2World world)
        {
            m_flags = 0;

            if (bd.bullet)
            {
                m_flags |= b2BodyFlags.e_bulletFlag;
            }
            if (bd.fixedRotation)
            {
                m_flags |= b2BodyFlags.e_fixedRotationFlag;
            }
            if (bd.allowSleep)
            {
                m_flags |= b2BodyFlags.e_autoSleepFlag;
            }
            if (bd.awake)
            {
                m_flags |= b2BodyFlags.e_awakeFlag;
            }
            if (bd.active)
            {
                m_flags |= b2BodyFlags.e_activeFlag;
            }

            m_world = world;

            m_xf.p = bd.position;
            m_xf.q.Set(bd.angle);

            m_sweep.localCenter.SetZero();
            m_sweep.c0 = m_xf.p;
            m_sweep.c = m_xf.p;
            m_sweep.a0 = bd.angle;
            m_sweep.a = bd.angle;
            m_sweep.alpha0 = 0.0f;

            m_jointList = null;
            m_contactList = null;
            m_prev = null;
            m_next = null;

            m_linearVelocity = bd.linearVelocity;
            m_angularVelocity = bd.angularVelocity;

            m_linearDamping = bd.linearDamping;
            m_angularDamping = bd.angularDamping;
            m_gravityScale = bd.gravityScale;

            m_force.SetZero();
            m_torque = 0.0f;

            m_sleepTime = 0.0f;

            m_type = bd.type;

            if (m_type == b2BodyType.b2_dynamicBody)
            {
                m_mass = 1.0f;
                m_invMass = 1.0f;
            }
            else
            {
                m_mass = 0.0f;
                m_invMass = 0.0f;
            }

            m_I = 0.0f;
            m_invI = 0.0f;

            m_userData = bd.userData;

            m_fixtureList = null;
            m_fixtureCount = 0;
        }
예제 #47
0
public virtual bool ShouldCollide(b2Body other)
{
    // At least one body should be dynamic.
    if (m_type != b2_dynamicBody && other.m_type != b2_dynamicBody)
    {
        return false;
    }

    // Does a joint prevent collision?
    for (b2JointEdge* jn = m_jointList; jn; jn = jn.next)
    {
        if (jn.other == other)
        {
            if (jn.joint.m_collideConnected == false)
            {
                return false;
            }
        }
    }

    return true;
}
예제 #48
0
        public Test()
        {
            m_destructionListener = new DestructionListener();
            m_debugDraw = new CCBox2dDraw("fonts/arial-12", 1);

            b2Vec2 gravity = new b2Vec2();
            gravity.Set(0.0f, -10.0f);
            m_world = new b2World(gravity);
            m_bomb = null;
            m_textLine = 30;
            m_mouseJoint = null;
            m_pointCount = 0;

            m_destructionListener.test = this;
            m_world.SetDestructionListener(m_destructionListener);
            m_world.SetContactListener(this);
            m_world.SetDebugDraw(m_debugDraw);
            m_world.SetContinuousPhysics(true);
            m_world.SetWarmStarting(true);

            m_bombSpawning = false;

            m_stepCount = 0;

            b2BodyDef bodyDef = new b2BodyDef();
            m_groundBody = m_world.CreateBody(bodyDef);
        }
예제 #49
0
        public void Destroy(b2Contact c)
        {
            b2Fixture fixtureA = c.FixtureA;
            b2Fixture fixtureB = c.FixtureB;
            b2Body    bodyA    = fixtureA.Body;
            b2Body    bodyB    = fixtureB.Body;

            if (m_contactListener != null && c.IsTouching())
            {
                m_contactListener.EndContact(c);
            }

            // Remove from the world.
            if (c.Prev != null)
            {
                c.Prev.Next = c.Next;
            }

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

            if (c == m_contactList)
            {
                m_contactList = c.Next;
            }

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

            if (c.NodeA.Next != null)
            {
                c.NodeA.Next.Prev = c.NodeA.Prev;
            }

            if (c.NodeA == bodyA.ContactList)
            {
                bodyA.ContactList = c.NodeA.Next;
            }

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

            if (c.NodeB.Next != null)
            {
                c.NodeB.Next.Prev = c.NodeB.Prev;
            }

            if (c.NodeB == bodyB.ContactList)
            {
                bodyB.ContactList = c.NodeB.Next;
            }

            c.Free();

            // Call the factory.
            --m_contactCount;
        }
예제 #50
0
        public void LaunchBomb(b2Vec2 position, b2Vec2 velocity)
        {
            if (m_bomb != null)
            {
                m_world.DestroyBody(m_bomb);
                m_bomb = null;
            }

            b2BodyDef bd = new b2BodyDef();
            bd.type = b2BodyType.b2_dynamicBody;
            bd.position = position;
            bd.bullet = true;
            m_bomb = m_world.CreateBody(bd);
            m_bomb.LinearVelocity = velocity;

            b2CircleShape circle = new b2CircleShape();
            circle.Radius = 0.3f;

            b2FixtureDef fd = new b2FixtureDef();
            fd.shape = circle;
            fd.density = 20.0f;
            fd.restitution = 0.0f;

            b2Vec2 minV = position - new b2Vec2(0.3f, 0.3f);
            b2Vec2 maxV = position + new b2Vec2(0.3f, 0.3f);

            b2AABB aabb = new b2AABB();
            aabb.LowerBound = minV;
            aabb.UpperBound = maxV;

            m_bomb.CreateFixture(fd);
        }
예제 #51
0
        public void DestroyBody(b2Body b)
        {
            if (IsLocked())
            {
                return;
            }

            // Delete the attached joints.
            b2JointEdge je = b.JointList;

            while (je)
            {
                b2JointEdge je0 = je;
                je = je.next;

                if (m_destructionListener != null)
                {
                    m_destructionListener.SayGoodbye(je0.joint);
                }

                DestroyJoint(je0.joint);

                b.JointList = je;
            }
            b.JointList = null;

            // Delete the attached contacts.
            b2ContactEdge ce = b.ContactList;

            while (ce)
            {
                b2ContactEdge ce0 = ce;
                ce = ce.next;
                m_contactManager.Destroy(ce0.contact);
            }
            b.ContactList = null;

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

            while (f != null)
            {
                b2Fixture f0 = f;
                f = f.Next;

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

                f0.DestroyProxies(m_contactManager.BroadPhase);

                b.FixtureList   = f;
                b.FixtureCount -= 1;
            }
            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 == m_bodyList)
            {
                m_bodyList = b.Next;
            }

            --m_bodyCount;
        }
예제 #52
0
        public virtual bool ShouldCollide(b2Body other)
        {
            // At least one body should be dynamic.
            if (m_type != b2BodyType.b2_dynamicBody && other.m_type != b2BodyType.b2_dynamicBody)
            {
                return false;
            }

            // Does a joint prevent collision?
            for (b2JointEdge jn = m_jointList; jn != null; jn = jn.Next)
            {
                if (jn.Other == other)
                {
                    if (jn.Joint.GetCollideConnected() == false)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
예제 #53
0
        public void DestroyJoint(b2Joint j)
        {
            if (IsLocked())
            {
                return;
            }

            bool collideConnected = j.m_collideConnected;

            // Remove from the doubly linked list.
            if (j.Prev)
            {
                j.Prev.Next = j.Next;
            }

            if (j.Next)
            {
                j.Next.Prev = j.Prev;
            }

            if (j == m_jointList)
            {
                m_jointList = j.Next;
            }

            // Disconnect from island graph.
            b2Body bodyA = j.m_bodyA;
            b2Body bodyB = j.m_bodyB;

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

            // Remove from body 1.
            if (j.m_edgeA.prev)
            {
                j.m_edgeA.prev.next = j.m_edgeA.next;
            }

            if (j.m_edgeA.next)
            {
                j.m_edgeA.next.prev = j.m_edgeA.prev;
            }

            if (j.m_edgeA == bodyA.JointList)
            {
                bodyA.JointList = j.m_edgeA.next;
            }

            j.m_edgeA.prev = null;
            j.m_edgeA.next = null;

            // Remove from body 2
            if (j.m_edgeB.prev)
            {
                j.m_edgeB.prev.next = j.m_edgeB.next;
            }

            if (j.m_edgeB.next)
            {
                j.m_edgeB.next.prev = j.m_edgeB.prev;
            }

            if (j.m_edgeB == bodyB.JointList)
            {
                bodyB.JointList = j.m_edgeB.next;
            }

            j.m_edgeB.prev = null;
            j.m_edgeB.next = null;

            b2Joint.Destroy(j);

            --m_jointCount;

            // If the joint prevents collisions, then flag any contacts for filtering.
            if (collideConnected == false)
            {
                b2ContactEdge edge = bodyB.ContactList;
                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;
                }
            }
        }
예제 #54
0
        public void SolveTOI(b2TimeStep subStep)
        {
            int i;
            int j;

            m_contactSolver.Initialize(subStep, m_contacts, m_contactCount, m_allocator);
            b2ContactSolver contactSolver = m_contactSolver;

            // No warm starting is needed for TOI events because warm
            // starting impulses were applied in the discrete solver.

            // Warm starting for joints is off for now, but we need to
            // call this function to compute Jacobians.
            for (i = 0; i < m_jointCount; ++i)
            {
                m_joints[i].InitVelocityConstraints(subStep);
            }


            // Solve velocity constraints.
            for (i = 0; i < subStep.velocityIterations; ++i)
            {
                contactSolver.SolveVelocityConstraints();
                for (j = 0; j < m_jointCount; ++j)
                {
                    m_joints[j].SolveVelocityConstraints(subStep);
                }
            }

            // Don't store the TOI contact forces for warm starting
            // because they can be quite large.

            // Integrate positions.
            for (i = 0; i < m_bodyCount; ++i)
            {
                b2Body b = m_bodies[i];

                if (b.GetType() == b2Body.b2_staticBody)
                {
                    continue;
                }

                // Check for large velocities.
                // b2Vec2 translation = subStep.dt * b.m_linearVelocity;
                float translationX = subStep.dt * b.m_linearVelocity.x;
                float translationY = subStep.dt * b.m_linearVelocity.y;
                //if (b2Dot(translation, translation) > b2_maxTranslationSquared)
                if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared)
                {
                    b.m_linearVelocity.Normalize();
                    b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt;
                    b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt;
                }

                float rotation = subStep.dt * b.m_angularVelocity;
                if (rotation * rotation > b2Settings.b2_maxRotationSquared)
                {
                    if (b.m_angularVelocity < 0.0f)
                    {
                        b.m_angularVelocity = -b2Settings.b2_maxRotation * subStep.inv_dt;
                    }
                    else
                    {
                        b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt;
                    }
                }

                // Store positions for continuous collision.
                b.m_sweep.c0.SetV(b.m_sweep.c);
                b.m_sweep.a0 = b.m_sweep.a;

                // Integrate
                b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x;
                b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y;
                b.m_sweep.a   += subStep.dt * b.m_angularVelocity;

                // Compute new transform
                b.SynchronizeTransform();

                // Note: shapes are synchronized later.
            }

            // Solve position constraints.
            float k_toiBaumgarte = 0.75f;

            for (i = 0; i < subStep.positionIterations; ++i)
            {
                bool contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte);
                bool jointsOkay   = true;
                for (j = 0; j < m_jointCount; ++j)
                {
                    bool jointOkay = m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
                    jointsOkay = jointsOkay && jointOkay;
                }

                if (contactsOkay && jointsOkay)
                {
                    break;
                }
            }
            Report(contactSolver.m_constraints);
        }
예제 #55
0
        // Find islands, integrate and solveraints, solve positionraints
        public void Solve(b2TimeStep step)
        {
            m_profile.solveInit     = 0.0f;
            m_profile.solveVelocity = 0.0f;
            m_profile.solvePosition = 0.0f;

            // Size the island for the worst case.
            b2Island island = new b2Island(m_bodyCount,
                                           m_contactManager.ContactCount,
                                           m_jointCount,
                                           m_contactManager.ContactListener);

            // Clear all the island flags.
            for (b2Body b = m_bodyList; b != null; b = b.Next)
            {
                b.BodyFlags &= ~b2BodyFlags.e_islandFlag;
            }
            for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
            {
                c.ContactFlags &= ~b2ContactFlags.e_islandFlag;
            }
            for (b2Joint j = m_jointList; j; j = j.Next)
            {
                j.m_islandFlag = false;
            }

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

            b2Body[] stack = new b2Body[stackSize];
            for (b2Body seed = m_bodyList; seed != null; seed = seed.Next)
            {
                if (seed.BodyFlags & b2BodyFlags.e_islandFlag)
                {
                    continue;
                }

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

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

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

                // Perform a depth first search (DFS) on theraint graph.
                while (stackCount > 0)
                {
                    // Grab the next body off the stack and add it to the island.
                    b2Body b = stack[--stackCount];
                    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.BodyType == b2BodyType.b2_staticBody)
                    {
                        continue;
                    }

                    // Search all contacts connected to this body.
                    for (b2ContactEdge ce = b.ContactList; ce != null; ce = ce.next)
                    {
                        b2Contact contact = ce.contact;

                        // Has this contact already been added to an island?
                        if (contact.ContactFlags & b2ContactFlags.e_islandFlag)
                        {
                            continue;
                        }

                        // Is this contact solid and touching?
                        if (contact.IsEnabled() == false ||
                            contact.IsTouching() == false)
                        {
                            continue;
                        }

                        // Skip sensors.
                        bool sensorA = contact.m_fixtureA.m_isSensor;
                        bool sensorB = contact.m_fixtureB.m_isSensor;
                        if (sensorA || sensorB)
                        {
                            continue;
                        }

                        island.Add(contact);
                        contact.ContactFlags |= b2ContactType.e_islandFlag;

                        b2Body other = ce.other;

                        // Was the other body already added to this island?
                        if ((other.BodyFlags & b2BodyFlags.e_islandFlag) > 0)
                        {
                            continue;
                        }

                        stack[stackCount++] = other;
                        other.BodyFlags    |= b2BodyFlags.e_islandFlag;
                    }

                    // Search all joints connect to this body.
                    for (b2JointEdge je = b.JointList; je; je = je.next)
                    {
                        if (je.joint.IslandFlag == true)
                        {
                            continue;
                        }

                        b2Body other = je.other;

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

                        island.Add(je.joint);
                        je.joint.m_islandFlag = true;

                        if ((other.BodyFlags & b2BodyFlags.e_islandFlag) > 0)
                        {
                            continue;
                        }

                        stack[stackCount++] = other;
                        other.BodyFlags    |= b2BodyFlags.e_islandFlag;
                    }
                }

                b2Profile profile = island.Solve(step, m_gravity, m_allowSleep);
                m_profile.solveInit     += profile.solveInit;
                m_profile.solveVelocity += profile.solveVelocity;
                m_profile.solvePosition += profile.solvePosition;

                // Post solve cleanup.
                for (int i = 0; i < island.m_bodyCount; ++i)
                {
                    // Allow static bodies to participate in other islands.
                    b2Body b = island.m_bodies[i];
                    if (b.BodyType == b2BodyType.b2_staticBody)
                    {
                        b.BodyFlags &= ~b2BodyFlags.e_islandFlag;
                    }
                }
            }

            {
                b2Timer timer;
                // Synchronize fixtures, check for out of range bodies.
                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    // If a body was not in an island then it did not move.
                    if ((b.BodyFlags & b2BodyType.e_islandFlag) == 0)
                    {
                        continue;
                    }

                    if (b.GetBodyType() == b2BodyType.b2_staticBody)
                    {
                        continue;
                    }

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

                // Look for new contacts.
                m_contactManager.FindNewContacts();
                m_profile.broadphase = timer.GetMilliseconds();
            }
        }
예제 #56
0
        public void Create(b2Body body, b2FixtureDef def)
        {
            m_userData = def.userData;
            m_friction = def.friction;
            m_restitution = def.restitution;

            m_body = body;
            Next = null;

            m_filter = def.filter;

            m_isSensor = def.isSensor;

            m_shape = def.shape.Clone();

            // Reserve proxy space
            int childCount = m_shape.GetChildCount();
            for (int i = 0; i < childCount; ++i)
            {
                b2FixtureProxy proxy = new b2FixtureProxy();
                proxy.fixture = null;
                proxy.proxyId = b2BroadPhase.e_nullProxy;
                m_proxies.Add(proxy);
            }
            m_proxyCount = 0;

            m_density = def.density;
        }
예제 #57
0
        // This is the top level collision call for the time step. Here
        // all the narrow phase collision is processed for the world
        // contact list.
        public void Collide()
        {
            // Update awake contacts.
            b2Contact c = m_world.m_contactList;

            while (c != null)
            {
                b2Fixture fixtureA = c.GetFixtureA();
                b2Fixture fixtureB = c.GetFixtureB();
                b2Body    bodyA    = fixtureA.GetBody();
                b2Body    bodyB    = fixtureB.GetBody();
                if (bodyA.IsAwake() == false && bodyB.IsAwake() == false)
                {
                    c = c.GetNext();
                    continue;
                }

                b2Contact cNuke;

                // Is this contact flagged for filtering?
                if ((c.m_flags & b2Contact.e_filterFlag) > 0)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        cNuke = c;
                        c     = cNuke.GetNext();
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        cNuke = c;
                        c     = cNuke.GetNext();
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag
                    c.m_flags &= ~b2Contact.e_filterFlag;
                }

                object proxyA = fixtureA.m_proxy;
                object proxyB = fixtureB.m_proxy;

                bool overlap = m_broadPhase.TestOverlap(proxyA, proxyB);

                // Here we destroy contacts that cease to overlap in the broadphase
                if (overlap == false)
                {
                    cNuke = c;
                    c     = cNuke.GetNext();
                    Destroy(cNuke);
                    continue;
                }

                c.Update(m_contactListener);
                c = c.GetNext();
            }
        }
            public Wheel(
                b2World b2world,

                double x,
                double y,
                double width,
                double length,
                bool revolving,
                bool powered
                )
            {
                this.revolving = revolving;
                this.powered = powered;

                this.Initialize = car =>
                {

                    /*
                    wheel object 

                    pars:

                    car - car this wheel belongs to
                    x - horizontal position in meters relative to car's center
                    y - vertical position in meters relative to car's center
                    width - width in meters
                    length - length in meters
                    revolving - does this wheel revolve when steering?
                    powered - is this wheel powered?
                    */

                    var position = new double[] { x, y };
                    //this.car=pars.car;
                    //this.revolving=pars.revolving;
                    //this.powered=pars.powered;

                    //initialize body
                    var def = new b2BodyDef();
                    def.type = b2Body.b2_dynamicBody;
                    def.position = car.body.GetWorldPoint(new b2Vec2(position[0], position[1]));
                    def.angle = car.body.GetAngle();
                    this.body = b2world.CreateBody(def);

                    //initialize shape
                    var fixdef = new b2FixtureDef();
                    fixdef.density = 1;
                    fixdef.isSensor = true; //wheel does not participate in collision calculations: resulting complications are unnecessary

                    var fixdef_shape = new b2PolygonShape();

                    fixdef.shape = fixdef_shape;
                    fixdef_shape.SetAsBox(width / 2, length / 2);
                    body.CreateFixture(fixdef);

                    var jointdef = new b2RevoluteJointDef();

                    //create joint to connect wheel to body
                    if (revolving)
                    {
                        jointdef.Initialize(car.body, body, body.GetWorldCenter());
                        jointdef.enableMotor = false; //we'll be controlling the wheel's angle manually
                    }
                    else
                    {
                        jointdef.Initialize(car.body, body, body.GetWorldCenter()
                            //, new b2Vec2(1, 0)
                            );
                        jointdef.enableLimit = true;


                        //jointdef.lowerTranslation = 0;
                        //jointdef.upperTranslation = 0;
                    }
                    b2world.CreateJoint(jointdef);

                    #region setAngle
                    this.setAngle =
                        (angle) =>
                        {
                            /*
                            angle - wheel angle relative to car, in degrees
                            */
                            body.SetAngle(car.body.GetAngle() + angle.DegreesToRadians());
                        };
                    #endregion


                    #region getLocalVelocity
                    Func<double[]> getLocalVelocity = delegate
                    {
                        /*returns get velocity vector relative to car
                        */
                        var res = car.body.GetLocalVector(car.body.GetLinearVelocityFromLocalPoint(new b2Vec2(position[0], position[1])));
                        return new double[] { res.x, res.y };
                    };
                    #endregion



                    #region getDirectionVector
                    Func<double[]> getDirectionVector = delegate
                    {
                        /*
                        returns a world unit vector pointing in the direction this wheel is moving
                        */

                        if (getLocalVelocity()[1] > 0)
                            return vectors.rotate(new double[] { 0, 1 }, body.GetAngle());
                        else
                            return vectors.rotate(new double[] { 0, -1 }, body.GetAngle());
                    };
                    #endregion


                    #region getKillVelocityVector
                    Func<double[]> getKillVelocityVector = delegate
                    {
                        /*
                        substracts sideways velocity from this wheel's velocity vector and returns the remaining front-facing velocity vector
                        */
                        var velocity = body.GetLinearVelocity();
                        var sideways_axis = getDirectionVector();
                        var dotprod = vectors.dot(new[] { velocity.x, velocity.y }, sideways_axis);
                        return new double[] { sideways_axis[0] * dotprod, sideways_axis[1] * dotprod };
                    };
                    #endregion

                    #region killSidewaysVelocity
                    this.killSidewaysVelocity = delegate
                    {
                        /*
                        removes all sideways velocity from this wheels velocity
                        */
                        var kv = getKillVelocityVector();

                        body.SetLinearVelocity(new b2Vec2(kv[0], kv[1]));

                    };
                    #endregion
                };

            }
예제 #59
0
        public b2World(b2Vec2 gravity)
        {
            m_destructionListener = null;
            m_debugDraw = null;

            m_bodyList = null;
            m_jointList = null;

            m_bodyCount = 0;
            m_jointCount = 0;

            m_warmStarting = true;
            m_continuousPhysics = true;
            m_subStepping = false;

            m_stepComplete = true;

            m_allowSleep = true;
            m_gravity = gravity;

            m_flags = b2WorldFlags.e_clearForces;

            m_inv_dt0 = 0.0f;

            // setup up our default Contact Manager
            m_contactManager = new b2ContactManager();
        }
예제 #60
0
 public string GetBodyName(b2Body body)
 {
     if (m_bodyToNameMap.ContainsKey(body))
         return m_bodyToNameMap[body];
     return null;
 }