public bool CallWildcardPreSolveB(cpSpace space)
        {
            cpCollisionHandler handler = this.handlerB;

            this.swapped = !this.swapped;
            bool retval = handler.preSolveFunc(this, space, handler.userData);

            this.swapped = !this.swapped;
            return(retval);
        }
示例#2
0
        public ulong CollideShapes(cpShape a, cpShape b, ulong id)
        {
            // It would be nicer to use .bind() or something, but this is faster.
            //return new Action<object, object>((obj1, obj2) =>
            //{// Reject any of the simple cases
            if (QueryReject(a, b))
            {
                return(id);
            }

            //contactsBuffer.Clear();

            List <cpContact> contacts = new List <cpContact>();

            // Narrow-phase collision detection.
            //int numContacts = cpCollideShapes(a, b, contacts);
            cpCollisionInfo info = cpCollision.cpCollide(a, b, id, ref contacts);

            if (info.count == 0)
            {
                return(info.id);                // Shapes are not colliding.
            }
            // Get an arbiter from space.arbiterSet for the two shapes.
            // This is where the persistant contact magic comes from.
            var arbHash = cp.CP_HASH_PAIR(info.a.hashid, info.b.hashid);

            cpArbiter arb;

            if (!cachedArbiters.TryGetValue(arbHash, out arb))
            {
                arb = new cpArbiter(a, b);
                cachedArbiters.Add(arbHash, arb);
            }

            arb.Update(info, this);

            cpCollisionHandler handler = arb.handler;              //LookupHandler(a.type, b.type, defaultHandler);


            // Call the begin function first if it's the first step
            if (arb.state == cpArbiterState.FirstCollision && !handler.beginFunc(arb, this, null))
            {
                arb.Ignore();                 // permanently ignore the collision until separation
            }

            if (
                // Ignore the arbiter if it has been flagged
                (arb.state != cpArbiterState.Ignore) &&
                // Call preSolve
                handler.preSolveFunc(arb, this, handler.userData) &&
                !(a.sensor || b.sensor) &&
                // Process, but don't add collisions for sensors.
                !(a.body.m == cp.Infinity && b.body.m == cp.Infinity)
                )
            {
                this.arbiters.Add(arb);
            }
            else
            {
                //cpSpacePopContacts(space, numContacts);

                arb.contacts.Clear();

                // Normally arbiters are set as used after calling the post-solve callback.
                // However, post-solve callbacks are not called for sensors or arbiters rejected from pre-solve.
                if (arb.state != cpArbiterState.Ignore)
                {
                    arb.state = cpArbiterState.Normal;
                }
            }

            // Time stamp the arbiter so we know it was used recently.
            arb.stamp = this.stamp;
            //	});
            return(info.id);
        }
        public bool CallWildcardPreSolveA(cpSpace space)
        {
            cpCollisionHandler handler = this.handlerA;

            return(handler.preSolveFunc(this, space, handler.userData));
        }