//MARK: Misc Helper Funcs // Default collision functions. static bool DefaultBegin(cpArbiter arb, cpSpace space, object data) { bool retA = arb.CallWildcardBeginA(space);// cpArbiterCallWildcardBeginA(arb, space); bool retB = arb.CallWildcardBeginB(space);// cpArbiterCallWildcardBeginB(arb, space); return retA && retB; }
public static cpArbiterThread ThreadForBody(cpArbiter arb, cpBody body) { return (arb.body_a == body ? arb.thread_a : arb.thread_b); }
public static bool CollisionBeginCallbackFunc(cpArbiter arb, cpSpace space, CCPhysicsWorld world) { cpShape a, b; arb.GetShapes(out a, out b); CCPhysicsShapeInfo ita = null, itb = null; cp.AssertWarn(CCPhysicsShapeInfo.Map.TryGetValue(a, out ita) && CCPhysicsShapeInfo.Map.TryGetValue(b, out itb)); if (a != null || b != null) return false; CCPhysicsContact contact = new CCPhysicsContact(ita.getShape(), itb.getShape()); arb.data = contact; contact._contactInfo = arb; return world.CollisionBeginCallback(contact); }
public static void CollisionPostSolveCallbackFunc(cpArbiter arb, cpSpace space, CCPhysicsWorld world) { world.CollisionPostSolveCallback((CCPhysicsContact)(arb.data)); }
public static void DefaultPostSolve(cpArbiter arb, cpSpace space, object o) { }
public static void DefaultSeparate(cpArbiter arb, cpSpace space, object o) { }
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 static bool AlwaysCollide(cpArbiter arb, cpSpace space, object data) { return true; }
/// <summary> /// CREATES A BODY WITH MASS AND INERTIA /// </summary> /// <param name="mass"></param> /// <param name="moment"></param> public cpBody(float mass, float moment) { transform = new cpTransform(); this.cog = cpVect.Zero; this.space = null; this.shapeList = null; this.arbiterList = null; // These are both wacky linked lists. this.constraintList = null; velocity_func = UpdateVelocity; position_func = UpdatePosition; // This stuff is used to track information on the collision graph. this.nodeRoot = null; this.nodeNext = null; this.nodeIdleTime = 0; /// Position of the rigid body's center of gravity. this.p = cpVect.Zero; /// Velocity of the rigid body's center of gravity. this.v = cpVect.Zero; /// Force acting on the rigid body's center of gravity. this.f = cpVect.Zero; /// Angular velocity of the body around it's center of gravity in radians/second. this.w = 0; /// Torque applied to the body around it's center of gravity. this.t = 0; // This stuff is all private. this.v_bias = cpVect.Zero; //x = this.v_biasy = 0; this.w_bias = 0; this.userData = null; this.SetMass(mass); this.SetMoment(moment); this.SetAngle(0.0f); }
//public void PushArbiter(cpArbiter arb) //{ // cp.assertSoft(cpArbiter.ThreadForBody(arb, this).next == null, "Internal Error: Dangling contact graph pointers detected. (A)"); // cp.assertSoft(cpArbiter.ThreadForBody(arb, this).prev == null, "Internal Error: Dangling contact graph pointers detected. (B)"); // cpArbiter next = this.arbiterList; // cp.assertSoft(next == null || cpArbiter.ThreadForBody(next, this).prev == null, "Internal Error: Dangling contact graph pointers detected. (C)"); // cpArbiterThread thread = cpArbiter.ThreadForBody(arb, this); // thread.next = next; // if (next != null) // { // var threadNext = cpArbiter.ThreadForBody(next, this); // threadNext.prev = arb; // } // this.arbiterList = arb; //} public void PushArbiter(cpArbiter arb) { cp.AssertSoft((arb.body_a == this ? arb.thread_a.next : arb.thread_b.next) == null, "Internal Error: Dangling contact graph pointers detected. (A)"); cp.AssertSoft((arb.body_a == this ? arb.thread_a.prev : arb.thread_b.prev) == null, "Internal Error: Dangling contact graph pointers detected. (B)"); var next = this.arbiterList; cp.AssertSoft(next == null || (next.body_a == this ? next.thread_a.prev : next.thread_b.prev) == null, "Internal Error: Dangling contact graph pointers detected. (C)"); if (arb.body_a == this) { arb.thread_a.next = next; } else { arb.thread_b.next = next; } if (next != null) { if (next.body_a == this) { next.thread_a.prev = arb; } else { next.thread_b.prev = arb; } } this.arbiterList = arb; }
static void DefaultSeparate(cpArbiter arb, cpSpace space, object data) { arb.CallWildcardSeparateA(space); arb.CallWildcardSeparateB(space); }
static bool DefaultPreSolve(cpArbiter arb, cpSpace space, object data) { bool retA = arb.CallWildcardPreSolveA(space); bool retB = arb.CallWildcardPreSolveB(space); return retA && retB; }
static void DefaultPostSolve(cpArbiter arb, cpSpace space, object data) { arb.CallWildcardPostSolveA(space); arb.CallWildcardPostSolveB(space); }
//public static void UnthreadHelper(cpArbiter arb, cpBody body) //{ // cpArbiterThread thread = arb.ThreadForBody(body); // cpArbiter prev = thread.prev; // cpArbiter next = thread.next; // // thread_x_y is quite ugly, but it avoids making unnecessary js objects per arbiter. // if (prev != null) // { // cpArbiterThread nextPrev = prev.ThreadForBody(body); // nextPrev.next = next; // } // else if (body.arbiterList == arb) // { // // IFF prev is NULL and body->arbiterList == arb, is arb at the head of the list. // // This function may be called for an arbiter that was never in a list. // // In that case, we need to protect it from wiping out the body->arbiterList pointer. // body.arbiterList = next; // } // if (next != null) // { // cpArbiterThread threadNext = next.ThreadForBody(body); // threadNext.prev = prev; // } // thread.prev = null; // thread.next = null; //} public static void UnthreadHelper(cpArbiter arb, cpBody body, cpArbiter prev, cpArbiter next) { // thread_x_y is quite ugly, but it avoids making unnecessary js objects per arbiter. if (prev != null) { // cpArbiterThreadForBody(prev, body)->next = next; if (prev.body_a == body) { prev.thread_a.next = next; } else { prev.thread_b.next = next; } } else { body.arbiterList = next; } if (next != null) { // cpArbiterThreadForBody(next, body)->prev = prev; if (next.body_a == body) { next.thread_a.prev = prev; } else { next.thread_b.prev = prev; } } }
static void DoNothing(cpArbiter arb, cpSpace space, object data) { }
public cpArbiterThread(cpArbiter next, cpArbiter prev) { this.next = next; this.prev = prev; }
public void UncacheArbiter(cpArbiter arb) { cachedArbiters.Remove(arb.Key); arbiters.Remove(arb); }
public static bool DefaultBegin(cpArbiter arb, cpSpace space, object o) { return true; }
public static bool DefaultPreSolve(cpArbiter arb, cpSpace space, object o) { return true; }
public static void DoNothing(cpArbiter arb, cpSpace space, object data) { }
static bool AlwaysCollide(cpArbiter arb, cpSpace space, object data) { return(true); }
public static bool CollisionPreSolveCallbackFunc(cpArbiter arb, cpSpace space, CCPhysicsWorld world) { return world.CollisionPreSolveCallback((CCPhysicsContact)(arb.data)); }
// Equal function for arbiterSet. public static bool SetEql(cpShape[] shapes, cpArbiter arb) { cpShape a = shapes[0]; cpShape b = shapes[1]; return ((a == arb.a && b == arb.b) || (b == arb.a && a == arb.b)); }
public static void CollisionSeparateCallbackFunc(cpArbiter arb, cpSpace space, CCPhysicsWorld world) { CCPhysicsContact contact = (CCPhysicsContact)(arb.data); if (contact != null) world.CollisionSeparateCallback(contact); //delete contact; }