Пример #1
0
        public override float ReportFixture(b2Fixture fixture, b2Vec2 point, b2Vec2 normal, float fraction)
        {
            if ((fixture.GetFilterData().categoryBits & _CollisionMask) == 0)
            {
                return(-1f);
            }
            ICollider collider = _Physics2DControl.GetPhysicsObject(fixture.GetBody().GetUserData().data).GetCollider(fixture.GetUserData().data);

            return(_Callback.Invoke(collider, point.ToVector2(), normal.ToVector2(), fraction));
        }
Пример #2
0
        public override bool ReportFixture(b2Fixture fixture)
        {
            if ((fixture.GetFilterData().categoryBits & _CollisionMask) == 0)
            {
                return(true);
            }
            ICollider collider = _Physics2DControl.GetPhysicsObject(fixture.GetBody().GetUserData().data).GetCollider(fixture.GetUserData().data);

            return(_Callback.Invoke(collider));
        }
Пример #3
0
        /** @private */
        virtual public void Reset(b2Fixture fixtureA = null, b2Fixture fixtureB = null)
        {
            m_flags = e_enabledFlag;

            if (fixtureA == null || fixtureB == null)
            {
                m_fixtureA = null;
                m_fixtureB = null;
                return;
            }

            if (fixtureA.IsSensor() || fixtureB.IsSensor())
            {
                m_flags |= e_sensorFlag;
            }

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

            if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet())
            {
                m_flags |= e_continuousFlag;
            }

            m_fixtureA = fixtureA;
            m_fixtureB = fixtureB;

            m_manifold.m_pointCount = 0;

            m_prev = null;
            m_next = null;

            m_nodeA.contact = null;
            m_nodeA.prev    = null;
            m_nodeA.next    = null;
            m_nodeA.other   = null;

            m_nodeB.contact = null;
            m_nodeB.prev    = null;
            m_nodeB.next    = null;
            m_nodeB.other   = null;
        }
Пример #4
0
    internal static void Destroy(ref b2Contact contact)
    {
        Debug.Assert(s_initialized == true);

        b2Fixture fixtureA = contact.m_fixtureA;
        b2Fixture fixtureB = contact.m_fixtureB;

        if (contact.m_manifold.pointCount > 0 && fixtureA.IsSensor() == false && fixtureB.IsSensor() == false)
        {
            fixtureA.GetBody().SetAwake(true);
            fixtureB.GetBody().SetAwake(true);
        }

        b2Shape.Type typeA = fixtureA.GetType();
        b2Shape.Type typeB = fixtureB.GetType();

        Debug.Assert(0 <= ((int)typeA) && typeB < b2Shape.Type.e_typeCount);
        Debug.Assert(0 <= ((int)typeA) && typeB < b2Shape.Type.e_typeCount);

        b2ContactDestroyFcn destroyFcn = s_registers[(int)typeA, (int)typeB].destroyFcn;

        destroyFcn(ref contact);
    }
Пример #5
0
        public override byte[] Render(bool toRgbArray = false)
        {
            if (Viewer == null)
            {
                Viewer = new Rendering.Viewer(VIEWPORT_W, VIEWPORT_H);
            }
            Viewer.SetBounds(scroll, VIEWPORT_W / SCALE + scroll, 0, VIEWPORT_H / SCALE);

            Viewer.DrawPolygon(new List <float[]> {
                new float[] { scroll, 0 },
                new float[] { scroll + VIEWPORT_W / SCALE, 0 },
                new float[] { scroll + VIEWPORT_W / SCALE, VIEWPORT_H / SCALE },
                new float[] { scroll, VIEWPORT_H / SCALE }
            }).SetColor(0.9f, 0.9f, 1.0f);

            foreach (var cloud_data in cloud_poly)
            {
                var poly     = cloud_data.Item1;
                var pos_data = cloud_data.Item2;

                if (pos_data.y < scroll / 2)
                {
                    continue;
                }
                if (pos_data.x > scroll / 2 + VIEWPORT_W / SCALE)
                {
                    continue;
                }
                Viewer.DrawPolygon(poly.Select(p => new[] { p[0] + scroll / 2, p[1] }).ToList()).SetColor(1, 1, 1);
            }
            foreach (var terrain_data in terrain_poly)
            {
                var poly  = terrain_data.Item1;
                var color = terrain_data.Item2;

                if (poly[1][0] < scroll)
                {
                    continue;
                }
                if (poly[0][0] > scroll + VIEWPORT_W / SCALE)
                {
                    continue;
                }
                Viewer.DrawPolygon(poly).SetColor(color.x, color.y, color.z);
            }

            lidar_render = (lidar_render + 1) % 100;
            int i = lidar_render;

            if (i < 2 * lidar.Length)
            {
                var l = i < lidar.Length ? lidar[i] : lidar[2 * lidar.Length - i - 1];
                Viewer.DrawPolyline(new List <float[]> {
                    new float[] { l.P1.x, l.P1.y }, new float[] { l.P2.x, l.P2.y }
                }).SetColor(1, 0, 0).SetLineWidth(1);
            }

            foreach (var obj in drawlist)
            {
                for (b2Fixture f = obj.GetFixtureList(); f != null; f = f.GetNext())
                {
                    var xform = f.GetBody().GetTransform();

                    if (f.GetShape() is b2CircleShape)
                    {
                        var shape      = (f.GetShape() as b2CircleShape);
                        var customData = (obj.GetUserData() as CustomBodyData);
                        var trans      = Utils.b2Mul(xform, shape.m_p);

                        var t = new Rendering.Transform(new float[] { trans[0], trans[1] });
                        Viewer.DrawCircle(shape.m_radius, 30).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z).AddAttr(t);
                        Viewer.DrawCircle(shape.m_radius, 30, false).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2).AddAttr(t);
                    }
                    else
                    {
                        var shape      = f.GetShape();
                        var customData = (obj.GetUserData() as CustomBodyData);

                        var path = shape.GetVertices().Select(v => { var trans = Utils.b2Mul(xform, v); return(new float[] { trans[0], trans[1] }); }).ToList();
                        Viewer.DrawPolygon(path).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z);
                        path.Add(path[0]);
                        Viewer.DrawPolyline(path).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2);
                    }
                }
            }

            var flagy1 = TERRAIN_HEIGHT;
            var flagy2 = flagy1 + 50 / SCALE;
            var x      = TERRAIN_STEP * 3;

            Viewer.DrawPolyline(new List <float[]> {
                new float[] { x, flagy1 }, new float[] { x, flagy2 }
            }).SetColor(0, 0, 0).SetLineWidth(2);
            var flagVert = new List <float[]> {
                new float[] { x, flagy2 }, new float[] { x, flagy2 - 10 / SCALE }, new float[] { x + 25 / SCALE, flagy2 - 5 / SCALE }
            };

            Viewer.DrawPolygon(flagVert).SetColor(0.9f, 0.2f, 0);
            flagVert.Add(flagVert[0]);
            Viewer.DrawPolyline(flagVert).SetColor(0, 0, 0).SetLineWidth(2);

            Viewer.Render();
            return(null);
        }
Пример #6
0
        public override byte[] Render(bool toRgbArray = false)
        {
            if (Viewer == null)
            {
                Viewer = new Rendering.Viewer(VIEWPORT_W, VIEWPORT_H);
                Viewer.SetBounds(0, VIEWPORT_W / SCALE, 0, VIEWPORT_H / SCALE);
            }

            foreach (var obj in particles)
            {
                var data = obj.GetUserData() as CustomBodyData;
                data.TimeToLive -= 0.15f;
                data.Color1      = new b2Vec3((float)Math.Max(0.2, 0.2 + data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive));
                data.Color2      = new b2Vec3((float)Math.Max(0.2, 0.2 + data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive));
            }

            CleanParticles(false);

            foreach (var p in sky_polys)
            {
                Viewer.DrawPolygon(p).SetColor(0, 0, 0);
            }

            foreach (var obj in particles.Concat(drawlist))
            {
                for (b2Fixture f = obj.GetFixtureList(); f != null; f = f.GetNext())
                {
                    var xform = f.GetBody().GetTransform();
                    if (f.GetShape() is b2CircleShape)
                    {
                        var shape      = (f.GetShape() as b2CircleShape);
                        var customData = (obj.GetUserData() as CustomBodyData);
                        var trans      = Utils.b2Mul(xform, shape.m_p);

                        var t = new Rendering.Transform(new float[] { trans[0], trans[1] });
                        Viewer.DrawCircle(shape.m_radius, 20).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z).AddAttr(t);
                        Viewer.DrawCircle(shape.m_radius, 20, false).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2).AddAttr(t);
                    }
                    else
                    {
                        var shape      = f.GetShape();
                        var customData = (obj.GetUserData() as CustomBodyData);

                        var path = shape.GetVertices().Select(v => { var trans = Utils.b2Mul(xform, v); return(new float[] { trans[0], trans[1] }); }).ToList();
                        Viewer.DrawPolygon(path).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z);
                        path.Add(path[0]);
                        Viewer.DrawPolyline(path).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2);
                    }
                }
            }


            foreach (var x in new[] { helipad_x1, helipad_x2 })
            {
                var flagy1 = helipad_y;
                var flagy2 = flagy1 + 50 / SCALE;
                Viewer.DrawPolyline(new List <float[]> {
                    new float[] { x, flagy1 }, new float[] { x, flagy2 }
                }).SetColor(1, 1, 1);
                Viewer.DrawPolygon(new List <float[]> {
                    new float[] { x, flagy2 }, new float[] { x, flagy2 - 10 / SCALE }, new float[] { x + 25 / SCALE, flagy2 - 5 / SCALE }
                }).SetColor(0.8f, 0.8f, 0);
            }

            Viewer.Render();
            return(null);
        }
Пример #7
0
    public b2ContactSolver(b2ContactSolverDef def)
    {
        m_step  = def.step;
        m_count = def.count;
        m_positionConstraints = Arrays.InitializeWithDefaultInstances <b2ContactPositionConstraint>(m_count);
        m_velocityConstraints = Arrays.InitializeWithDefaultInstances <b2ContactVelocityConstraint>(m_count);
        m_positions           = def.positions;
        m_velocities          = def.velocities;
        m_contacts            = def.contacts;

        // Initialize position independent portions of the constraints.
        for (int i = 0; i < m_count; ++i)
        {
            b2Contact contact = m_contacts[i];

            b2Fixture  fixtureA = contact.m_fixtureA;
            b2Fixture  fixtureB = contact.m_fixtureB;
            b2Shape    shapeA   = fixtureA.GetShape();
            b2Shape    shapeB   = fixtureB.GetShape();
            float      radiusA  = shapeA.m_radius;
            float      radiusB  = shapeB.m_radius;
            b2Body     bodyA    = fixtureA.GetBody();
            b2Body     bodyB    = fixtureB.GetBody();
            b2Manifold manifold = contact.GetManifold();

            int pointCount = manifold.pointCount;
            Debug.Assert(pointCount > 0);

            b2ContactVelocityConstraint vc = m_velocityConstraints[i];
            vc.friction     = contact.m_friction;
            vc.restitution  = contact.m_restitution;
            vc.tangentSpeed = contact.m_tangentSpeed;
            vc.indexA       = bodyA.m_islandIndex;
            vc.indexB       = bodyB.m_islandIndex;
            vc.invMassA     = bodyA.m_invMass;
            vc.invMassB     = bodyB.m_invMass;
            vc.invIA        = bodyA.m_invI;
            vc.invIB        = bodyB.m_invI;
            vc.contactIndex = i;
            vc.pointCount   = pointCount;
            vc.K.SetZero();
            vc.normalMass.SetZero();

            b2ContactPositionConstraint pc = m_positionConstraints[i];
            pc.indexA       = bodyA.m_islandIndex;
            pc.indexB       = bodyB.m_islandIndex;
            pc.invMassA     = bodyA.m_invMass;
            pc.invMassB     = bodyB.m_invMass;
            pc.localCenterA = bodyA.m_sweep.localCenter;
            pc.localCenterB = bodyB.m_sweep.localCenter;
            pc.invIA        = bodyA.m_invI;
            pc.invIB        = bodyB.m_invI;
            pc.localNormal  = manifold.localNormal;
            pc.localPoint   = manifold.localPoint;
            pc.pointCount   = pointCount;
            pc.radiusA      = radiusA;
            pc.radiusB      = radiusB;
            pc.type         = manifold.type;

            for (int j = 0; j < pointCount; ++j)
            {
                b2ManifoldPoint           cp  = manifold.points[j];
                b2VelocityConstraintPoint vcp = vc.points[j];

                if (m_step.warmStarting)
                {
                    vcp.normalImpulse  = m_step.dtRatio * cp.normalImpulse;
                    vcp.tangentImpulse = m_step.dtRatio * cp.tangentImpulse;
                }
                else
                {
                    vcp.normalImpulse  = 0.0f;
                    vcp.tangentImpulse = 0.0f;
                }

                vcp.rA.SetZero();
                vcp.rB.SetZero();
                vcp.normalMass   = 0.0f;
                vcp.tangentMass  = 0.0f;
                vcp.velocityBias = 0.0f;

                pc.localPoints[j] = cp.localPoint;
            }
        }
    }
Пример #8
0
    // Broad-phase callback.
    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 != null)
        {
            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 != null && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
        {
            return;
        }

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

        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
        if (fixtureA.IsSensor() == false && fixtureB.IsSensor() == false)
        {
            bodyA.SetAwake(true);
            bodyB.SetAwake(true);
        }

        ++m_contactCount;
    }
Пример #9
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 != null)
        {
            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.ContactFlags.e_filterFlag) != 0)
            {
                // Should these bodies collide?
                if (bodyB.ShouldCollide(bodyA) == false)
                {
                    b2Contact cNuke = c;
                    c = cNuke.GetNext();
                    Destroy(cNuke);
                    continue;
                }

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

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

            bool activeA = bodyA.IsAwake() && bodyA.m_type != BodyType.b2_staticBody;
            bool activeB = bodyB.IsAwake() && bodyB.m_type != BodyType.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();
        }
    }
Пример #10
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 != null && c.IsTouching())
        {
            m_contactListener.EndContact(c);
        }

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

        if (c.m_next != null)
        {
            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 != null)
        {
            c.m_nodeA.prev.next = c.m_nodeA.next;
        }

        if (c.m_nodeA.next != null)
        {
            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 != null)
        {
            c.m_nodeB.prev.next = c.m_nodeB.next;
        }

        if (c.m_nodeB.next != null)
        {
            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(ref c);
        --m_contactCount;
    }