예제 #1
0
        /// Test if a point lies within a shape.
        public static cpContactPointSet Collide(cpShape a, cpShape b, ref List <cpContact> contacts)
        {
            //cpContact[] contacts = new cpContact[cpArbiter.CP_MAX_CONTACTS_PER_ARBITER];
            cpCollisionInfo info = cpCollision.cpCollide(a, b, 0, ref contacts);

            cpContactPointSet set = new cpContactPointSet();

            set.count = info.count;

            set.points = new PointsDistance[set.count];

            // cpCollideShapes() may have swapped the contact order. Flip the normal.
            bool swapped = (a != info.a);

            set.normal = (swapped ? cpVect.cpvneg(info.n) : info.n);

            for (int i = 0; i < info.count; i++)
            {
                cpVect p1 = contacts[i].r1;
                cpVect p2 = contacts[i].r2;

                set.points[i]          = new PointsDistance();
                set.points[i].pointA   = (swapped ? p2 : p1);
                set.points[i].pointB   = (swapped ? p1 : p2);
                set.points[i].distance = cpVect.cpvdot(cpVect.cpvsub(p2, p1), set.normal);
            }

            return(set);
        }
예제 #2
0
        public void SetContactPointSet(ref cpContactPointSet set)
        {
            int count = set.count;

            cp.AssertHard(count == Count, "The number of contact points cannot be changed.");

            this.n = (this.swapped ? cpVect.cpvneg(set.normal) : set.normal);

            for (int i = 0; i < count; i++)
            {
                // Convert back to CoG relative offsets.
                cpVect p1 = set.points[i].pointA;
                cpVect p2 = set.points[i].pointB;

                this.contacts[i].r1 = cpVect.cpvsub(swapped ? p2 : p1, this.body_a.p);
                this.contacts[i].r2 = cpVect.cpvsub(swapped ? p1 : p2, this.body_b.p);
            }
        }
예제 #3
0
        public ulong ShapeQueryFunc(cpShape a, cpShape b, ulong id, ShapeQueryContext context)
        {
            if (cpShapeFilter.Reject(a.filter, b.filter) || a == b)
            {
                return(id);
            }

            List <cpContact>  contacts = new List <cpContact>();
            cpContactPointSet set      = cpShape.Collide(a, b, ref contacts);

            if (set.count > 0)
            {
                if (context.func != null)
                {
                    context.func(b, set, context.data);
                }
                context.anyCollision = !(a.sensor || b.sensor);
            }
            return(id);
        }
예제 #4
0
        /// Return a contact set from an arbiter.
        public cpContactPointSet GetContactPointSet()
        {
            cpContactPointSet set = new cpContactPointSet();

            set.count  = GetCount();
            set.points = new PointsDistance[set.count];

            bool swapped = this.swapped;

            set.normal = (swapped ? cpVect.cpvneg(this.n) : this.n);

            for (int i = 0; i < set.count; i++)
            {
                // Contact points are relative to body CoGs;
                cpVect p1 = cpVect.cpvadd(this.body_a.p, this.contacts[i].r1);
                cpVect p2 = cpVect.cpvadd(this.body_b.p, this.contacts[i].r2);

                set.points[i]          = new PointsDistance();
                set.points[i].pointA   = (swapped ? p2 : p1);
                set.points[i].pointB   = (swapped ? p1 : p2);
                set.points[i].distance = cpVect.cpvdot(cpVect.cpvsub(p2, p1), this.n);
            }
            return(set);
        }